V35
authorjoan <joan@abyz.co.uk>
Fri, 24 Jul 2015 20:17:29 +0000 (21:17 +0100)
committerjoan <joan@abyz.co.uk>
Fri, 24 Jul 2015 20:17:29 +0000 (21:17 +0100)
15 files changed:
command.c
pigpio.3
pigpio.c
pigpio.h
pigpio.py
pigpiod_if.3
pigpiod_if.c
pigpiod_if.h
pigs.1
setup.py
x_pigpio.c
x_pigpio.py
x_pigpiod_if.c
x_pigs
x_pipe

index 1bdb901d01fc88724dc244c1fd8d44ab7edf3c7e..41c35ff19af5e457725a6159f650dce481eb1253 100644 (file)
--- a/command.c
+++ b/command.c
@@ -26,7 +26,7 @@ For more information, please refer to <http://unlicense.org/>
 */
 
 /*
-This version is for pigpio version 34+
+This version is for pigpio version 35+
 */
 
 #include <stdio.h>
@@ -458,11 +458,14 @@ static errInfo_t errInfo[]=
    {PI_BAD_I2C_RLEN     , "bad I2C read length"},
    {PI_BAD_I2C_CMD      , "bad I2C command"},
    {PI_BAD_I2C_BAUD     , "bad I2C baud rate, not 50-500k"},
-   {PI_BAD_REPEAT_CNT   , "bad repeat count, not 2-max"},
-   {PI_BAD_REPEAT_WID   , "bad repeat wave id"},
-   {PI_TOO_MANY_COUNTS  , "too many chain counters"},
-   {PI_BAD_CHAIN_CMD    , "malformed chain command string"},
-   {PI_REUSED_WID       , "wave already used in chain"},
+   {PI_CHAIN_LOOP_CNT   , "bad chain loop count"},
+   {PI_BAD_CHAIN_LOOP   , "empty chain loop"},
+   {PI_CHAIN_COUNTER    , "too many chain counters"},
+   {PI_BAD_CHAIN_CMD    , "bad chain command"},
+   {PI_BAD_CHAIN_DELAY  , "bad chain delay micros"},
+   {PI_CHAIN_NESTING    , "chain counters nested too deeply"},
+   {PI_CHAIN_TOO_BIG    , "chain is too long"},
+   {PI_DEPRECATED       , "deprecated function removed"},
 
 };
 
@@ -535,6 +538,7 @@ int cmdParse(
    char c;
    uint32_t tp1, tp2, tp3;
    int8_t to1, to2, to3;
+   int eaten;
 
    /* Check that ext is big enough for the largest message. */
    if (ext_len < (4 * CMD_MAX_PARAM)) return CMD_EXT_TOO_SMALL;
@@ -865,12 +869,16 @@ int cmdParse(
 
             while (pars < CMD_MAX_PARAM)
             {
-               ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
-               if ((to1 == CMD_NUMERIC) &&
-                   ((int)tp1>=0) && ((int)tp1<=255))
+               eaten = getNum(buf+ctl->eaten, &tp1, &to1);
+               if (to1 == CMD_NUMERIC)
                {
-                  pars++;
-                  *p8++ = tp1;
+                  if (((int)tp1>=0) && ((int)tp1<=255))
+                  {
+                     pars++;
+                     *p8++ = tp1;
+                     ctl->eaten += eaten;
+                  }
+                  else break; /* invalid number, end of command */
                }
                else break;
             }
@@ -899,13 +907,16 @@ int cmdParse(
 
             while (pars < 32)
             {
-               ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
-               if ((to1 == CMD_NUMERIC) &&
-                  ((int)tp1>=0) &&
-                  ((int)tp1<=255))
+               eaten = getNum(buf+ctl->eaten, &tp1, &to1);
+               if (to1 == CMD_NUMERIC)
                {
-                  pars++;
-                  *p8++ = tp1;
+                  if (((int)tp1>=0) && ((int)tp1<=255))
+                  {
+                     pars++;
+                     *p8++ = tp1;
+                     ctl->eaten += eaten;
+                  }
+                  else break; /* invalid number, end of command */
                }
                else break;
             }
@@ -940,15 +951,16 @@ int cmdParse(
 
                      while (pars < CMD_MAX_PARAM)
                      {
-                        ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
+                        eaten = getNum(buf+ctl->eaten, &tp1, &to1);
                         if (to1 == CMD_NUMERIC)
                         {
                            if (((int)tp1>=0) && ((int)tp1<=255))
                            {
                               pars++;
                               *p8++ = tp1;
+                              ctl->eaten += eaten;
                            }
-                           else valid = 0;
+                           else break;
                         }
                         else break;
                      }
@@ -996,12 +1008,16 @@ int cmdParse(
             p8 = ext + 12;
             while (pars < CMD_MAX_PARAM)
             {
-               ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
-               if ((to1 == CMD_NUMERIC) &&
-                   ((int)tp1>=0) && ((int)tp1<=255))
+               eaten = getNum(buf+ctl->eaten, &tp1, &to1);
+               if (to1 == CMD_NUMERIC)
                {
-                  *p8++ = tp1;
-                  pars++;
+                  if (((int)tp1>=0) && ((int)tp1<=255))
+                  {
+                     *p8++ = tp1;
+                     pars++;
+                     ctl->eaten += eaten;
+                  }
+                  else break; /* invalid number, end of command */
                }
                else break;
             }
@@ -1022,12 +1038,16 @@ int cmdParse(
 
          while (pars < CMD_MAX_PARAM)
          {
-            ctl->eaten += getNum(buf+ctl->eaten, &tp1, &to1);
-            if ((to1 == CMD_NUMERIC) &&
-                ((int)tp1>=0) && ((int)tp1<=255))
+            eaten = getNum(buf+ctl->eaten, &tp1, &to1);
+            if (to1 == CMD_NUMERIC)
             {
-               pars++;
-               *p8++ = tp1;
+               if (((int)tp1>=0) && ((int)tp1<=255))
+               {
+                  pars++;
+                  *p8++ = tp1;
+                  ctl->eaten += eaten;
+               }
+               else break; /* invalid number, end of command */
             }
             else break;
          }
index 8d948bb06f1847686b8ae0c6508456271e5a825f..0006337fff689448b2b8674c17ea7c55fe2d5527 100644 (file)
--- a/pigpio.3
+++ b/pigpio.3
@@ -1683,8 +1683,9 @@ gpioWaveAddSerial(4, 9600, 8, 2, 1000000, MSG_LEN, data);
 .IP "\fBint gpioWaveCreate(void)\fP"
 .IP "" 4
 This function creates a waveform from the data provided by the prior
-calls to the \fBgpioWaveAdd*\fP functions.  Upon success a positive wave id
-is returned.
+calls to the \fBgpioWaveAdd*\fP functions.  Upon success a wave id
+greater than or equal to 0 is returned, otherwise PI_EMPTY_WAVEFORM,
+PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
 
 .br
 
@@ -1788,8 +1789,7 @@ PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
 
 .IP "\fBint gpioWaveDelete(unsigned wave_id)\fP"
 .IP "" 4
-This function deletes all created waveforms with ids greater than or
-equal to wave_id.
+This function deletes the waveform with id wave_id.
 
 .br
 
@@ -1811,38 +1811,6 @@ Wave ids are allocated in order, 0, 1, 2, etc.
 .br
 Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
 
-.IP "\fBint gpioWaveTxStart(unsigned wave_mode)\fP"
-.IP "" 4
-This function creates and then transmits a waveform.  The mode
-determines whether the waveform is sent once or cycles endlessly.
-
-.br
-
-.br
-NOTE: Any hardware PWM started by \fBgpioHardwarePWM\fP will be cancelled.
-
-.br
-
-.br
-
-.EX
-wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT)
-.br
-
-.EE
-
-.br
-
-.br
-This function is deprecated and should no longer be used.  Use
-\fBgpioWaveCreate\fP and \fBgpioWaveTxSend\fP instead.
-
-.br
-
-.br
-Returns the number of DMA control blocks in the waveform if OK,
-otherwise PI_BAD_WAVE_MODE.
-
 .IP "\fBint gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)\fP"
 .IP "" 4
 This function transmits the waveform with id wave_id.  The mode
@@ -1884,7 +1852,7 @@ NOTE: Any hardware PWM started by \fBgpioHardwarePWM\fP will be cancelled.
 
 .br
 The waves to be transmitted are specified by the contents of buf
-which contains an ordered list of wave_ids and optional command
+which contains an ordered list of \fBwave_id\fPs and optional command
 codes and related data.
 
 .br
@@ -1902,24 +1870,26 @@ bufSize: the number of bytes in buf
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
-PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+Returns 0 if OK, otherwise PI_CHAIN_NESTING, PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD, PI_CHAIN_COUNTER,
+PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG, or PI_BAD_WAVE_ID.
 
 .br
 
 .br
-Each wave is transmitted in the order specified.  A wave may only
-occur once per chain.  Waves may be transmitted multiple times by
-using the repeat command.  The repeat command specifies a wave id
-and a count.  The wave id must occur earlier in the chain.  All the
-waves between wave id and the repeat command are transmitted count
-times.
+Each wave is transmitted in the order specified.  A wave may
+occur multiple times per chain.
 
 .br
 
 .br
-Repeat commands may not be nested.  The minimum repeat count is 2.
-A maximum of 5 repeat commands is supported per chain.
+A blocks of waves may be transmitted multiple times by using
+the loop commands. The block is bracketed by loop start and
+end commands.  Loops may be nested.
+
+.br
+
+.br
+Delays between waves may be added with the delay command.
 
 .br
 
@@ -1929,13 +1899,24 @@ The following command codes are supported:
 .br
 
 .br
-Name      Cmd & Data         Meaning
+Name          Cmd & Data   Meaning
 
 .br
-Repeat    255 wid C0 C1 C2   Repeat from wid count times
+Loop Start    255 0        Identify start of a wave block
 
 .br
-count = C0 + C1*256 + C2*65536
+Loop Repeat   255 1 x y    loop x + y*256 times
+
+.br
+Delay         255 2 x y    delay x + y*256 microseconds
+
+.br
+
+.br
+
+.br
+The code is currently dimensioned to support a chain with roughly
+600 entries and 20 loop counters.
 
 .br
 
@@ -1944,55 +1925,109 @@ count = C0 + C1*256 + C2*65536
 .br
 
 .EX
-The following examples assume that waves with ids 0 to 12 exist.
+#include <stdio.h>
+.br
+#include <pigpio.h>
 .br
 
 .br
-// 0 255 0 57 0 0 (repeat 0 57 times)
+#define WAVES 5
 .br
-status = gpioWaveChain((char []){0, 255, 0, 57, 0, 0}, 6);
+#define GPIO 4
 .br
 
 .br
-// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+int main(int argc, char *argv[])
+.br
+{
 .br
-status = gpioWaveChain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+   int i, wid[WAVES];
 .br
 
 .br
-// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+   if (gpioInitialise()<0) return -1;
 .br
-status = gpioWaveChain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+
+.br
+   gpioSetMode(GPIO, PI_OUTPUT);
 .br
 
 .br
-// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+   printf("start piscope, press return\n"); getchar();
+.br
+
+.br
+   for (i=0; i<WAVES; i++)
+.br
+   {
+.br
+      gpioWaveAddGeneric(2, (gpioPulse_t[])
 .br
-status = gpioWaveChain(
+         {{1<<GPIO, 0,        20},
 .br
-   (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+          {0, 1<<GPIO, (i+1)*200}});
 .br
 
 .br
-// The following repeats 5 65793 times, transmits 6,
+      wid[i] = gpioWaveCreate();
+.br
+   }
+.br
+
+.br
+   gpioWaveChain((char []) {
+.br
+      wid[4], wid[3], wid[2],       // transmit waves 4+3+2
+.br
+      255, 0,                       // loop start
+.br
+         wid[0], wid[0], wid[0],    // transmit waves 0+0+0
+.br
+         255, 0,                    // loop start
+.br
+            wid[0], wid[1],         // transmit waves 0+1
 .br
-// repeats 7+8 514 times, transmits 12,
+            255, 2, 0x88, 0x13,     // delay 5000us
 .br
-// repeats 9+11+10 197121 times.
+         255, 1, 30, 0,             // loop end (repeat 30 times)
 .br
-// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+         255, 0,                    // loop start
 .br
-char chain[] = {
+            wid[2], wid[3], wid[0], // transmit waves 2+3+0
 .br
-   5,             255, 5, 1, 1, 1,
+            wid[3], wid[1], wid[2], // transmit waves 3+1+2
 .br
-   6, 7, 8,       255, 7, 2, 2, 0,
+         255, 1, 10, 0,             // loop end (repeat 10 times)
 .br
-   12, 9, 11, 10, 255, 9, 1, 2, 3};
+      255, 1, 5, 0,                 // loop end (repeat 5 times)
+.br
+      wid[4], wid[4], wid[4],       // transmit waves 4+4+4
+.br
+      255, 2, 0x20, 0x4E,           // delay 20000us
+.br
+      wid[0], wid[0], wid[0],       // transmit waves 0+0+0
+.br
+
+.br
+      }, 46);
 .br
 
 .br
-status = gpioWaveChain(chain, sizeof(chain));
+   while (gpioWaveTxBusy()) time_sleep(0.1);
+.br
+
+.br
+   for (i=0; i<WAVES; i++) gpioWaveDelete(wid[i]);
+.br
+
+.br
+   printf("stop piscope, press return\n"); getchar();
+.br
+
+.br
+   gpioTerminate();
+.br
+}
 .br
 
 .EE
@@ -4386,8 +4421,8 @@ Frequencies above 30MHz are unlikely to work.
 .br
 
 .br
-NOTE: Any waveform started by \fBgpioWaveTxSend\fP, \fBgpioWaveTxStart\fP,
-or \fBgpioWaveChain\fP will be cancelled.
+NOTE: Any waveform started by \fBgpioWaveTxSend\fP, or
+\fBgpioWaveChain\fP will be cancelled.
 
 .br
 
@@ -7022,7 +7057,7 @@ Denoting no parameter is required
 .br
 
 .br
-A number representing a waveform created by \fBgpioWaveCreate\fP.
+A number identifying a waveform created by \fBgpioWaveCreate\fP.
 
 .br
 
@@ -7514,15 +7549,21 @@ A 16-bit word value.
 .br
 #define PI_BAD_I2C_BAUD    -112 // bad I2C baud rate, not 50-500k
 .br
-#define PI_BAD_REPEAT_CNT  -113 // bad repeat count, not 2-max
+#define PI_CHAIN_LOOP_CNT  -113 // bad chain loop count
+.br
+#define PI_BAD_CHAIN_LOOP  -114 // empty chain loop
+.br
+#define PI_CHAIN_COUNTER   -115 // too many chain counters
+.br
+#define PI_BAD_CHAIN_CMD   -116 // bad chain command
 .br
-#define PI_BAD_REPEAT_WID  -114 // bad repeat wave id
+#define PI_BAD_CHAIN_DELAY -117 // bad chain delay micros
 .br
-#define PI_TOO_MANY_COUNTS -115 // too many chain counters
+#define PI_CHAIN_NESTING   -118 // chain counters nested too deeply
 .br
-#define PI_BAD_CHAIN_CMD   -116 // malformed chain command string
+#define PI_CHAIN_TOO_BIG   -119 // chain is too long
 .br
-#define PI_REUSED_WID      -117 // wave already used in chain
+#define PI_DEPRECATED      -120 // deprecated function removed
 .br
 
 .br
index 66aef15f2d688e3e6820def16d0339013fcb6acb..4e2f9fa18bf9cf1314a0b581f55c17aa8d57524b 100644 (file)
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 For more information, please refer to <http://unlicense.org/>
 */
 
-/* pigpio version 34 */
+/* pigpio version 35 */
 
 /* include ------------------------------------------------------- */
 
@@ -626,7 +626,10 @@ bit 0 READ_LAST_NOT_SET_ERROR
 
 #define NORMAL_DMA (DMA_NO_WIDE_BURSTS | DMA_WAIT_RESP)
 
-#define TIMED_DMA(x)  (DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(x))
+#define TIMED_DMA(x) (DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(x))
+
+#define PCM_TIMER (((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS)
+#define PWM_TIMER (((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS)
 
 #define DBG_MIN_LEVEL 0
 #define DBG_ALWAYS    0
@@ -669,6 +672,28 @@ bit 0 READ_LAST_NOT_SET_ERROR
 #define CBS_PER_OPAGE 118
 #define OOL_PER_OPAGE  79
 
+/*
+Wave Count Block
+
+Assumes two counters per block.  Each counter 4 * 16 (16^4=65536)
+   0  CB [13]  13*8  104 CBs for counter 0
+ 104  CB [13]  13*8  104 CBs for counter 1
+ 208  CB [60]  60*8  480 CBs reserved to construct wave
+ 688 OOL [60]  60*1   60 OOL reserved to construct wave
+ 748 OOL[136] 136*1  136 OOL for counter 0
+ 884 OOL[136] 136*1  136 OOL for counter 1
+1020 pad  [4]   4*1    4 spare
+*/
+
+#define WCB_CNT_PER_PAGE 2
+#define WCB_COUNTERS (WCB_CNT_PER_PAGE * PI_WAVE_COUNT_PAGES)
+#define WCB_CNT_CBS 13
+#define WCB_CNT_OOL 68
+#define WCB_COUNTER_OOL (WCB_CNT_PER_PAGE * WCB_CNT_OOL)
+#define WCB_COUNTER_CBS (WCB_CNT_PER_PAGE * WCB_CNT_CBS)
+#define WCB_CHAIN_CBS   60
+#define WCB_CHAIN_OOL   60
+
 #define CBS_PER_CYCLE ((PULSE_PER_CYCLE*3)+2)
 
 #define NUM_CBS (CBS_PER_CYCLE * bufferCycles)
@@ -1086,9 +1111,8 @@ static rawWaveInfo_t waveInfo[PI_MAX_WAVES];
 
 static wfRx_t wfRx[PI_MAX_USER_GPIO+1];
 
-static int waveOutBotCB  = PI_WAVE_COUNTERS*CBS_PER_OPAGE;
-static int waveOutTopCB  = NUM_WAVE_CBS;
-static int waveOutBotOOL = PI_WAVE_COUNTERS*OOL_PER_OPAGE;
+static int waveOutBotCB  = PI_WAVE_COUNT_PAGES*CBS_PER_OPAGE;
+static int waveOutBotOOL = PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE;
 static int waveOutTopOOL = NUM_WAVE_OOL;
 static int waveOutCount = 0;
 
@@ -1312,6 +1336,9 @@ static void initHWClk
 
 static void initDMAgo(volatile uint32_t  *dmaAddr, uint32_t cbAddr);
 
+int gpioWaveTxStart(unsigned wave_mode); /* deprecated */
+
+
 /* ======================================================================= */
 
 static char * myTimeStamp()
@@ -2461,19 +2488,6 @@ static uint32_t waveOOLPOadr(int pos)
 }
 
 
-/* ----------------------------------------------------------------------- */
-
-static void waveCbOPrint(int pos)
-{
-   rawCbs_t * p;
-
-   p = rawWaveCBAdr(pos);
-
-   fprintf(stderr, "i=%x s=%x d=%x len=%x s=%x nxt=%x\n",
-      p->info, p->src, p->dst, p->length, p->stride, p->next);
-}
-
-
 /* ----------------------------------------------------------------------- */
 
 static void waveBitDelay
@@ -2501,20 +2515,42 @@ static void waveBitDelay
 
 /* ----------------------------------------------------------------------- */
 
-static int errCBsOOL(int cb, int botOOL, int topOOL)
+static void waveCBsOOLs(int *numCBs, int *numBOOLs, int *numTOOLs)
 {
-   if (cb >= waveOutTopCB) return PI_TOO_MANY_CBS;
+   int numCB=0, numBOOL=0, numTOOL=0;
 
-   if (botOOL >= topOOL) return PI_TOO_MANY_OOL;
+   unsigned i;
 
-   return 0;
+   unsigned numWaves;
+
+   rawWave_t *waves;
+
+   numWaves = wfc[wfcur];
+   waves    = wf [wfcur];
+
+   /* delay cb at start of DMA */
+
+   numCB++;
+
+   for (i=0; i<numWaves; i++)
+   {
+      if (waves[i].gpioOn)                 {numCB++; numBOOL++;}
+      if (waves[i].gpioOff)                {numCB++; numBOOL++;}
+      if (waves[i].flags & WAVE_FLAG_READ) {numCB++; numTOOL++;}
+      if (waves[i].flags & WAVE_FLAG_TICK) {numCB++; numTOOL++;}
+      if (waves[i].usDelay)                {numCB++;           }
+   }
+
+   *numCBs   = numCB;
+   *numBOOLs = numBOOL;
+   *numTOOLs = numTOOL;
 }
 
 /* ----------------------------------------------------------------------- */
 
-static int wave2Cbs(unsigned wave_mode)
+static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL)
 {
-   int botCB=waveOutBotCB, botOOL=waveOutBotOOL, topOOL=waveOutTopOOL;
+   int botCB=*CB, botOOL=*BOOL, topOOL=*TOOL;
 
    int status;
 
@@ -2531,8 +2567,6 @@ static int wave2Cbs(unsigned wave_mode)
 
    half = PI_WF_MICROS/2;
 
-   if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status;
-
    /* add delay cb at start of DMA */
 
    p = rawWaveCBAdr(botCB++);
@@ -2541,17 +2575,13 @@ static int wave2Cbs(unsigned wave_mode)
 
    if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
    {
-      p->info   = NORMAL_DMA |
-                  DMA_DEST_DREQ |
-                  DMA_PERIPHERAL_MAPPING(2);
-      p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS;
+      p->info = NORMAL_DMA | TIMED_DMA(2);
+      p->dst  = PCM_TIMER;
    }
    else
    {
-      p->info   = NORMAL_DMA |
-                  DMA_DEST_DREQ |
-                  DMA_PERIPHERAL_MAPPING(5);
-      p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS;
+      p->info = NORMAL_DMA | TIMED_DMA(5);
+      p->dst  = PWM_TIMER;
    }
 
    p->src    = (uint32_t) (&dmaOBus[0]->periphData);
@@ -2564,8 +2594,6 @@ static int wave2Cbs(unsigned wave_mode)
    {
       if (waves[i].gpioOn)
       {
-         if ((status = errCBsOOL(botCB+1, botOOL+1, topOOL))) return status;
-
          waveSetOOL(botOOL, waves[i].gpioOn);
 
          p = rawWaveCBAdr(botCB++);
@@ -2579,8 +2607,6 @@ static int wave2Cbs(unsigned wave_mode)
 
       if (waves[i].gpioOff)
       {
-         if ((status = errCBsOOL(botCB+1, botOOL+1, topOOL))) return status;
-
          waveSetOOL(botOOL, waves[i].gpioOff);
 
          p = rawWaveCBAdr(botCB++);
@@ -2594,8 +2620,6 @@ static int wave2Cbs(unsigned wave_mode)
 
       if (waves[i].flags & WAVE_FLAG_READ)
       {
-         if ((status = errCBsOOL(botCB+1, botOOL, topOOL-1))) return status;
-
          p = rawWaveCBAdr(botCB++);
 
          p->info   = NORMAL_DMA;
@@ -2607,8 +2631,6 @@ static int wave2Cbs(unsigned wave_mode)
 
       if (waves[i].flags & WAVE_FLAG_TICK)
       {
-         if ((status = errCBsOOL(botCB+1, botOOL, topOOL-1))) return status;
-
          p = rawWaveCBAdr(botCB++);
 
          p->info   = NORMAL_DMA;
@@ -2620,27 +2642,19 @@ static int wave2Cbs(unsigned wave_mode)
 
       if (waves[i].usDelay)
       {
-         if ((status = errCBsOOL(botCB+1, botOOL, topOOL))) return status;
-
          p = rawWaveCBAdr(botCB++);
 
          /* use the secondary clock */
 
          if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
          {
-            p->info   = NORMAL_DMA |
-                        DMA_DEST_DREQ |
-                        DMA_PERIPHERAL_MAPPING(2);
-
-            p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS;
+            p->info = NORMAL_DMA | TIMED_DMA(2);
+            p->dst  = PCM_TIMER;
          }
          else
          {
-            p->info   = NORMAL_DMA |
-                        DMA_DEST_DREQ |
-                        DMA_PERIPHERAL_MAPPING(5);
-
-            p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS;
+            p->info = NORMAL_DMA | TIMED_DMA(5);
+            p->dst  = PWM_TIMER;
          }
 
          p->src    = (uint32_t) (&dmaOBus[0]->periphData);
@@ -2656,113 +2670,15 @@ static int wave2Cbs(unsigned wave_mode)
       else p->next = waveCbPOadr(repeatCB);
    }
 
-   status = botCB - waveOutBotCB;
+   status = botCB - *CB;
 
-   waveOutBotCB  = botCB;
-   waveOutBotOOL = botOOL;
-   waveOutTopOOL = topOOL;
+   *CB   = botCB;
+   *BOOL = botOOL;
+   *TOOL = topOOL;
 
    return status;
 }
 
-/* ----------------------------------------------------------------------- */
-
-static uint32_t waveGetIn(int page, int slot)
-{
-   return (dmaOVirt[page]->OOL[slot]);
-}
-
-static void waveSetIn(int page, int slot, uint32_t value)
-{
-   dmaOVirt[page]->OOL[slot] = value;
-}
-
-static uint32_t myWaveOOLPOadr(int page, int slot)
-{
-   return (uint32_t) &dmaOBus[page]->OOL[slot];
-}
-
-static void waveCount(
-   unsigned counter,
-   unsigned blklen,
-   unsigned blocks,
-   unsigned count,
-   uint32_t repeat,
-   uint32_t next)
-{
-   rawCbs_t *p=NULL;
-
-   int b, baseCB, dig;
-   uint32_t nxt;
-
-   int botCB;
-
-   botCB  = counter * CBS_PER_OPAGE;
-
-   baseCB = botCB;
-
-   /* set up all the OOLs */
-   for (b=0; b < (blocks*(blklen+1)); b++) waveSetIn(counter, b, repeat);
-
-   for (b=0; b<blocks; b++)
-      waveSetIn(counter, ((b*(blklen+1))+blklen), waveCbPOadr(baseCB+((b*3)+3)));
-
-   for (b=0; b<blocks; b++)
-   {
-      /* copy BOTTOM to NEXT */
-
-      p = rawWaveCBAdr(botCB++);
-
-      p->info = NORMAL_DMA;
-
-      p->src = myWaveOOLPOadr(counter, b*(blklen+1));
-      p->dst = (waveCbPOadr(botCB+1) + 20);
-
-      p->length = 4;
-      p->next   = waveCbPOadr(botCB);
-
-      /* copy BOTTOM to TOP */
-
-      p = rawWaveCBAdr(botCB++);
-
-      p->info   = NORMAL_DMA;
-
-      p->src = myWaveOOLPOadr(counter, b*(blklen+1));
-      p->dst = myWaveOOLPOadr(counter, (b*(blklen+1))+blklen);
-
-      p->length = 4;
-      p->next   = waveCbPOadr(botCB);
-
-      /* shift all down one */
-
-      p = rawWaveCBAdr(botCB++);
-
-      p->info   = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
-
-      p->src = myWaveOOLPOadr(counter, ((b*(blklen+1))+1));
-      p->dst = myWaveOOLPOadr(counter, ((b*(blklen+1))+0));
-
-      p->length = blklen*4;
-      p->next   = repeat;
-   }
-
-   b = 0;
-
-   while (count && (b<blocks))
-   {
-      dig = count % blklen;
-      count /= blklen;
-
-      if (count) nxt = waveGetIn(counter, (b*(blklen+1))+blklen);
-      else       nxt = next;
-
-      waveSetIn(counter, b*(blklen+1)+dig, nxt);
-
-      b++;
-   }
-}
-
-
 /* ----------------------------------------------------------------------- */
 
 static void waveRxSerial(wfRx_t *w, int level, uint32_t tick)
@@ -4894,13 +4810,13 @@ static void dmaDelayCb(int b)
 
    if (gpioCfg.clockPeriph == PI_CLOCK_PCM)
    {
-      p->info   = NORMAL_DMA | TIMED_DMA(2);
-      p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS;
+      p->info = NORMAL_DMA | TIMED_DMA(2);
+      p->dst  = PCM_TIMER;
    }
    else
    {
-      p->info   = NORMAL_DMA | TIMED_DMA(5);
-      p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_BUS;
+      p->info = NORMAL_DMA | TIMED_DMA(5);
+      p->dst  = PWM_TIMER;
    }
 
    p->src    = dmaPwmDataAdr(b%DMAI_PAGES);
@@ -7463,9 +7379,6 @@ void gpioTerminate(void)
 
 static void switchFunctionOff(unsigned gpio)
 {
-   unsigned clock, pwm;
-   int cctl[] = {CLK_GP0_CTL, CLK_GP1_CTL, CLK_GP2_CTL};
-
    switch (gpioInfo[gpio].is)
    {
       case GPIO_SERVO:
@@ -7481,17 +7394,12 @@ static void switchFunctionOff(unsigned gpio)
          break;
 
       case GPIO_HW_CLK:
-         /* switch hardware clock off */
-         clock = (clkDef[gpio] >> 4) & 3;
-         clkReg[cctl[clock]] = CLK_PASSWD | CLK_CTL_KILL;
+         /* No longer disable clock hardware, doing that was a bug. */
          gpioInfo[gpio].width = 0;
          break;
 
       case GPIO_HW_PWM:
-         /* switch hardware PWM off */
-         pwm = (PWMDef[gpio] >> 4) & 3;
-         if (pwm == 0) pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN1);
-         else          pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN2);
+         /* No longer disable PWM hardware, doing that was a bug. */
          gpioInfo[gpio].width = 0;
          break;
    }
@@ -7499,14 +7407,18 @@ static void switchFunctionOff(unsigned gpio)
 
 static void stopHardwarePWM(void)
 {
-   int i;
+   unsigned i, pwm;
 
    for (i=0; i<= PI_MAX_GPIO; i++)
    {
       if (gpioInfo[i].is == GPIO_HW_PWM)
       {
-         switchFunctionOff(i);
+         pwm = (PWMDef[i] >> 4) & 3;
 
+         if (pwm == 0) pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN1);
+         else          pwmReg[PWM_CTL] &= (~PWM_CTL_PWEN2);
+
+         gpioInfo[i].width = 0;
          gpioInfo[i].is = GPIO_UNDEFINED;
       }
    }
@@ -7953,9 +7865,8 @@ int gpioWaveClear(void)
    wfStats.pulses = 0;
    wfStats.cbs    = 0;
 
-   waveOutBotCB  = PI_WAVE_COUNTERS*CBS_PER_OPAGE;
-   waveOutTopCB  = NUM_WAVE_CBS;
-   waveOutBotOOL = PI_WAVE_COUNTERS*OOL_PER_OPAGE;
+   waveOutBotCB  = PI_WAVE_COUNT_PAGES*CBS_PER_OPAGE;
+   waveOutBotOOL = PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE;
    waveOutTopOOL = NUM_WAVE_OOL;
 
    waveOutCount = 0;
@@ -8041,7 +7952,8 @@ int gpioWaveAddSerial
    if ((baud < PI_WAVE_MIN_BAUD) || (baud > PI_WAVE_MAX_BAUD))
       SOFT_ERROR(PI_BAD_WAVE_BAUD, "bad baud rate (%d)", baud);
 
-   if ((data_bits < PI_MIN_WAVE_DATABITS) || (data_bits > PI_MAX_WAVE_DATABITS))
+   if ((data_bits < PI_MIN_WAVE_DATABITS) ||
+       (data_bits > PI_MAX_WAVE_DATABITS))
       SOFT_ERROR(PI_BAD_DATABITS, "bad number of databits (%d)", data_bits);
 
    if ((stop_bits < PI_MIN_WAVE_HALFSTOPBITS) ||
@@ -8286,7 +8198,9 @@ int rawWaveAddSPI(
 
 int gpioWaveCreate(void)
 {
-   int cb;
+   int i, wid;
+   int numCB, numBOOL, numTOOL;
+   int CB, BOOL, TOOL;
 
    DBG(DBG_USER, "");
 
@@ -8294,95 +8208,126 @@ int gpioWaveCreate(void)
 
    if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM;
 
-   if (waveOutCount < PI_MAX_WAVES)
+   /* What resources are needed? */
+
+   waveCBsOOLs(&numCB, &numBOOL, &numTOOL);
+
+   wid = -1;
+
+   /* Is there an exact fit with a deleted wave. */
+
+   for (i=0; i<waveOutCount; i++)
+   {
+      if (waveInfo[i].deleted             &&
+         (waveInfo[i].numCB   == numCB)   &&
+         (waveInfo[i].numBOOL == numBOOL) &&
+         (waveInfo[i].numTOOL == numTOOL))
+      {
+         /* Reuse the deleted waves resources. */
+         wid = i;
+         break;
+      }
+   }
+
+   if (wid == -1)
    {
-      waveInfo[waveOutCount].botCB  = waveOutBotCB;
-      waveInfo[waveOutCount].botOOL = waveOutBotOOL;
-      waveInfo[waveOutCount].topOOL = waveOutTopOOL;
+      /* Are there enough spare resources? */
 
-      if ((cb = wave2Cbs(PI_WAVE_MODE_ONE_SHOT)) < 0) return cb;
+      if ((numCB+waveOutBotCB) >= NUM_WAVE_CBS)
+         return PI_TOO_MANY_CBS;
 
-      waveInfo[waveOutCount].topCB  = waveOutBotCB-1;
+      if ((numBOOL+waveOutBotOOL) >= (waveOutTopOOL-numTOOL))
+         return PI_TOO_MANY_OOL;
 
-      gpioWaveAddNew();
+      if (wid >= PI_MAX_WAVES)
+         return PI_NO_WAVEFORM_ID;
 
-      return waveOutCount++;
+      wid = waveOutCount++;
+
+      waveInfo[wid].botCB  = waveOutBotCB;
+      waveInfo[wid].topCB  = waveOutBotCB + numCB -1;
+      waveInfo[wid].botOOL = waveOutBotOOL;
+      waveInfo[wid].topOOL = waveOutTopOOL;
+      waveInfo[wid].numCB = numCB;
+      waveInfo[wid].numBOOL = numBOOL;
+      waveInfo[wid].numTOOL = numTOOL;
+
+      waveOutBotCB += numCB;
+      waveOutBotOOL += numBOOL;
+      waveOutTopOOL -= numTOOL;
    }
 
-   return PI_NO_WAVEFORM_ID;
-}
+   /* Must be room if got this far. */
 
-/* ----------------------------------------------------------------------- */
+   CB   = waveInfo[wid].botCB;
+   BOOL = waveInfo[wid].botOOL;
+   TOOL = waveInfo[wid].topOOL;
 
-int gpioWaveDelete(unsigned wave_id)
-{
-   DBG(DBG_USER, "wave id=%d", wave_id);
+   wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL);
 
-   CHECK_INITED;
+   /* Sanity check. */
 
-   if (wave_id >= waveOutCount)
-      SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
+   if ( (numCB   != (CB-waveInfo[wid].botCB))    ||
+        (numBOOL != (BOOL-waveInfo[wid].botOOL)) ||
+        (numTOOL != (waveInfo[wid].topOOL-TOOL)) )
+   {
+      DBG(0, "ERROR wid=%d CBs %d=%d BOOL %d=%d TOOL %d=%d", wid,
+         numCB,   CB-waveInfo[wid].botCB,
+         numBOOL, BOOL-waveInfo[wid].botOOL,
+         numTOOL, waveInfo[wid].topOOL-TOOL);
+   }
 
-   waveOutBotCB  = waveInfo[wave_id].botCB;
-   waveOutBotOOL = waveInfo[wave_id].botOOL;
-   waveOutTopOOL = waveInfo[wave_id].topOOL;
+   waveInfo[wid].deleted = 0;
 
-   waveOutCount = wave_id;
+   /* Consume waves. */
 
-   return 0;
+   wfc[0] = 0;
+   wfc[1] = 0;
+   wfc[2] = 0;
+
+   wfcur = 0;
+
+   return wid;
 }
 
 /* ----------------------------------------------------------------------- */
 
-int gpioWaveTxStart(unsigned wave_mode)
+int gpioWaveDelete(unsigned wave_id)
 {
-   /* This function is deprecated and will be removed. */
-
-   int firstCB=PI_WAVE_COUNTERS*CBS_PER_OPAGE;
-   int numCBs, i;
-
-   DBG(DBG_USER, "wave_mode=%d", wave_mode);
+   DBG(DBG_USER, "wave id=%d", wave_id);
 
    CHECK_INITED;
 
-   if (wave_mode > PI_WAVE_MODE_REPEAT)
-      SOFT_ERROR(PI_BAD_WAVE_MODE, "bad wave mode (%d)", wave_mode);
+   if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
+      SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
 
-   if (wfc[wfcur] == 0) return 0;
+   waveInfo[wave_id].deleted = 1;
 
-   if (!waveClockInited)
+   if (wave_id == (waveOutCount-1))
    {
-      stopHardwarePWM();
-      initClock(0); /* initialise secondary clock */
-      waveClockInited = 1;
-   }
+      /* top wave deleted, garbage collect any other deleted waves */
 
-   dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
+      while ((wave_id > 0) && (waveInfo[wave_id-1].deleted)) --wave_id;
 
-   dmaOut[DMA_CONBLK_AD] = 0;
+      waveOutBotCB  = waveInfo[wave_id].botCB;
+      waveOutBotOOL = waveInfo[wave_id].botOOL;
+      waveOutTopOOL = waveInfo[wave_id].topOOL;
 
-   waveOutBotCB  = firstCB;
-   waveOutTopCB  = NUM_WAVE_CBS;
-   waveOutBotOOL = PI_WAVE_COUNTERS*OOL_PER_OPAGE;
-   waveOutTopOOL = NUM_WAVE_OOL;
-
-   waveOutCount = 0;
+      waveOutCount = wave_id;
+   }
 
-   numCBs = wave2Cbs(wave_mode);
+   return 0;
+}
 
-   if (numCBs > 0)
-   {
-      if (gpioCfg.dbgLevel >= DBG_SLOW_TICK)
-      {
-         fprintf(stderr, "*** OUTPUT DMA CONTROL BLOCKS ***\n");
-         for (i=0; i<numCBs; i++) waveCbOPrint(firstCB+i);
-      }
+/* ----------------------------------------------------------------------- */
 
-      initDMAgo((uint32_t *)dmaOut, waveCbPOadr(firstCB));
-   }
+int gpioWaveTxStart(unsigned wave_mode)
+{
+   /* This function is deprecated and has been removed. */
 
-   return numCBs;
+   CHECK_INITED;
 
+   SOFT_ERROR(PI_DEPRECATED, "deprected function removed");
 }
 
 /* ----------------------------------------------------------------------- */
@@ -8395,7 +8340,7 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
 
    CHECK_INITED;
 
-   if (wave_id >= waveOutCount)
+   if ((wave_id >= waveOutCount) || waveInfo[wave_id].deleted)
       SOFT_ERROR(PI_BAD_WAVE_ID, "bad wave id (%d)", wave_id);
 
    if (wave_mode > PI_WAVE_MODE_REPEAT)
@@ -8425,16 +8370,201 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
    return (waveInfo[wave_id].topCB - waveInfo[wave_id].botCB) + 1;
 }
 
+
 /* ----------------------------------------------------------------------- */
 
+static int chainGetCB(int n)
+{
+   int block, index;
+
+   if (n < (WCB_CHAIN_CBS * PI_WAVE_COUNT_PAGES))
+   {
+      block = n / WCB_CHAIN_CBS;
+      index = n % WCB_CHAIN_CBS;
+      return (block*CBS_PER_OPAGE) + WCB_COUNTER_CBS + index;
+   }
+   return -1;
+}
+
+static void chainSetVal(int n, uint32_t val)
+{
+   int block, index;
+   uint32_t *p;
+
+   if (n < (WCB_CHAIN_OOL * PI_WAVE_COUNT_PAGES))
+   {
+      block = n / WCB_CHAIN_OOL;
+      index = n % WCB_CHAIN_OOL;
+      p = (uint32_t *) dmaOVirt[block] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
+      p[index] = val;
+   }
+}
+
+static uint32_t chainGetValPadr(int n)
+{
+   int block, index;
+   uint32_t *p;
+
+   if (n < (WCB_CHAIN_OOL * PI_WAVE_COUNT_PAGES))
+   {
+      block = n / WCB_CHAIN_OOL;
+      index = n % WCB_CHAIN_OOL;
+      p = (uint32_t *) dmaOBus[block] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
+      return (uint32_t) (p + index);
+   }
+   return 0;
+}
+
+static uint32_t chainGetCntVal(int counter, int slot)
+{
+   uint32_t *p;
+   int page, offset;
+   page = counter / 2;
+   offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
+   p = (uint32_t *) dmaOVirt[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
+   return p[WCB_CHAIN_OOL+ offset + slot];
+}
+
+static void chainSetCntVal(int counter, int slot, uint32_t value)
+{
+   uint32_t *p;
+   int page, offset;
+   page = counter / 2;
+   offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
+   p = (uint32_t *) dmaOVirt[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
+   p[WCB_CHAIN_OOL + offset + slot] = value;
+}
+
+static uint32_t chainGetCntValPadr(int counter, int slot)
+{
+   uint32_t *p;
+   int page, offset;
+   page = counter / 2;
+   offset = (counter % 2 ? WCB_COUNTER_OOL : 0);
+   p = (uint32_t *) dmaOBus[page] + (WCB_COUNTER_CBS+WCB_CHAIN_CBS) * 8;
+   return (uint32_t)(p + WCB_CHAIN_OOL + offset + slot);
+}
+
+static int chainGetCntCB(int counter)
+{
+   int page, offset;
+   page = counter / 2;
+   offset = (counter % 2 ? WCB_CNT_CBS : 0);
+   return ((page * CBS_PER_OPAGE) + offset);
+}
+
+static void chainMakeCounter(
+   unsigned counter,
+   unsigned blklen,
+   unsigned blocks,
+   unsigned count,
+   uint32_t repeat,
+   uint32_t next)
+{
+   rawCbs_t *p=NULL;
+
+   int b, baseCB, dig;
+   uint32_t nxt;
+
+   int botCB;
+
+   botCB  = chainGetCntCB(counter);
+
+   baseCB = botCB;
+
+   /* set up all the OOLs */
+   for (b=0; b < (blocks*(blklen+1)); b++) chainSetCntVal(counter, b, repeat);
+
+   for (b=0; b<blocks; b++)
+      chainSetCntVal(counter,
+         ((b*(blklen+1))+blklen),
+         waveCbPOadr(baseCB+((b*3)+3)));
+
+   for (b=0; b<blocks; b++)
+   {
+      /* copy BOTTOM to NEXT */
+
+      p = rawWaveCBAdr(botCB++);
+
+      p->info = NORMAL_DMA;
+
+      p->src = chainGetCntValPadr(counter, b*(blklen+1));
+      p->dst = (waveCbPOadr(botCB+1) + 20);
+
+      p->length = 4;
+      p->next   = waveCbPOadr(botCB);
+
+      /* copy BOTTOM to TOP */
+
+      p = rawWaveCBAdr(botCB++);
+
+      p->info   = NORMAL_DMA;
+
+      p->src = chainGetCntValPadr(counter, b*(blklen+1));
+      p->dst = chainGetCntValPadr(counter, (b*(blklen+1))+blklen);
+
+      p->length = 4;
+      p->next   = waveCbPOadr(botCB);
+
+      /* shift all down one */
+
+      p = rawWaveCBAdr(botCB++);
+
+      p->info   = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
+
+      p->src = chainGetCntValPadr(counter, ((b*(blklen+1))+1));
+      p->dst = chainGetCntValPadr(counter, ((b*(blklen+1))+0));
+
+      p->length = blklen*4;
+      p->next   = repeat;
+   }
+
+   /* reset the counter */
+
+   p = rawWaveCBAdr(botCB);
+
+   p->info = NORMAL_DMA|DMA_SRC_INC|DMA_DEST_INC;
+
+   p->src = chainGetCntValPadr(counter, blocks*(blklen+1));
+   p->dst = chainGetCntValPadr(counter, 0);
+
+   p->length = blocks*(blklen+1)*4;
+   p->next   = next;
+
+   b = 0;
+
+   while (count && (b<blocks))
+   {
+      dig = count % blklen;
+      count /= blklen;
+
+      if (count) nxt = chainGetCntVal(counter, (b*(blklen+1))+blklen);
+      else       nxt = waveCbPOadr(botCB);
+
+      chainSetCntVal(counter, b*(blklen+1)+dig, nxt);
+
+      b++;
+   }
+
+   /* copy all the OOLs */
+   for (b=0; b < (blocks*(blklen+1)); b++)
+      chainSetCntVal(
+         counter, b+(blocks*(blklen+1)), chainGetCntVal(counter, b));
+}
+
+
 int gpioWaveChain(char *buf, unsigned bufSize)
 {
-   unsigned blklen=8, blocks=8;
-   int i, wid, rwid, nwid, firstCB, lastCB, counters, cycles;
+   unsigned blklen=16, blocks=4;
+   int cb, chaincb;
+   rawCbs_t *p;
+   int i, wid, cmd, loop, counters;
+   unsigned cycles;
    uint32_t repeat, next;
-   char used[256];
+   int stk_pos[10], stk_lev=0;
 
-   rawCbs_t *p=NULL;
+   cb = 0;
+   loop = -1;
 
    DBG(DBG_USER, "bufSize=%d [%s]", bufSize, myBuf2Str(bufSize, buf));
 
@@ -8451,12 +8581,29 @@ int gpioWaveChain(char *buf, unsigned bufSize)
 
    dmaOut[DMA_CONBLK_AD] = 0;
 
-   for (i=0; i<256; i++) used[i] = 255;
+   /* add delay cb at start of DMA */
+
+   p = rawWaveCBAdr(chainGetCB(cb++));
+
+   /* use the secondary clock */
+
+   if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
+   {
+      p->info = NORMAL_DMA | TIMED_DMA(2);
+      p->dst  = PCM_TIMER;
+   }
+   else
+   {
+      p->info = NORMAL_DMA | TIMED_DMA(5);
+      p->dst  = PWM_TIMER;
+   }
+
+   p->src    = (uint32_t) (&dmaOBus[0]->periphData);
+   p->length = 4 * 20 / PI_WF_MICROS; /* 20 micros delay */
+   p->next   = waveCbPOadr(chainGetCB(cb));
 
    counters = 0;
    wid = -1;
-   lastCB = -1;
-   firstCB = -1;
 
    i = 0;
 
@@ -8464,92 +8611,183 @@ int gpioWaveChain(char *buf, unsigned bufSize)
    {
       wid = (unsigned)buf[i];
 
-      if (wid == 255) /* repeat wave command */
+      if (wid == 255) /* wave command */
       {
-         if (counters < PI_WAVE_COUNTERS)
+         if ((i+2) > bufSize)
+            SOFT_ERROR(PI_BAD_CHAIN_CMD,
+               "incomplete chain command (at %d)", i);
+
+         cmd = buf[i+1];
+
+         if (cmd == 0) /* loop begin */
          {
-            if ((i+4) < bufSize)
+            if (stk_lev >= (sizeof(stk_pos)/sizeof(int)))
+               SOFT_ERROR(PI_CHAIN_NESTING,
+                  "chain counters nested too deep (at %d)", i);
+
+            stk_pos[stk_lev++] = cb;
+            i += 2;
+         }
+         else if (cmd == 1) /* loop end */
+         {
+            if (counters >= WCB_COUNTERS)
+               SOFT_ERROR(PI_CHAIN_COUNTER,
+                  "too many chain counters (at %d)", i);
+
+            if ((i+4) > bufSize)
+               SOFT_ERROR(PI_BAD_CHAIN_CMD,
+                  "incomplete chain command (at %d)", i);
+
+            loop = 0;
+            if (--stk_lev >= 0) loop = stk_pos[stk_lev];
+
+            if ((loop < 1) || (loop == cb))
+               SOFT_ERROR(PI_BAD_CHAIN_LOOP,
+                  "empty chain loop (at %d)", i);
+
+            cycles = ((unsigned)buf[i+3] <<  8) + (unsigned)buf[i+2];
+
+            i += 4;
+
+            if (cycles > PI_MAX_WAVE_CYCLES)
+               SOFT_ERROR(PI_CHAIN_LOOP_CNT,
+                  "bad chain loop count (%d)", cycles);
+
+            if (cycles == 0)
             {
-               rwid = buf[i+1];
-               if ((i+5) < bufSize)
-               {
-                  nwid = buf[i+5];
-                  if (nwid < waveOutCount)
-                     next = waveCbPOadr(1+waveInfo[nwid].botCB);
-                  else next = 0; /* error, will be picked up later */
-               }
-               else next = 0;
-               if (used[rwid] == counters)
-               {
-                  repeat = waveCbPOadr(1+waveInfo[rwid].botCB);
+               /* Skip the complete loop block.  Change
+                  the next pointing to the start of the
+                  loop block to the current cb.
+               */
+               p = rawWaveCBAdr(chainGetCB(loop));
+               p->next = waveCbPOadr(chainGetCB(cb));
+            }
+            else if (cycles == 1)
+            {
+               /* Nothing to do, no need for a counter. */
+            }
+            else
+            {
+               chaincb = chainGetCB(cb++);
+               if (chaincb < 0)
+                  SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
 
-                  cycles = (unsigned)buf[i+2] +
-                           ((unsigned)buf[i+3]<<8) +
-                           ((unsigned)buf[i+4]<<16);
+               p = rawWaveCBAdr(chaincb);
 
-                  i+=4;
+               repeat = waveCbPOadr(chainGetCB(loop));
 
-                  if ((cycles > 1) && (cycles < PI_MAX_WAVE_CYCLES))
-                  {
-                     --cycles;
+                /* Need to check next cb as well. */
 
-                     waveCount(counters, blklen, blocks, cycles, repeat, next);
+               chaincb = chainGetCB(cb);
 
-                     p = rawWaveCBAdr(lastCB);
+               if (chaincb < 0)
+                  SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
 
-                     lastCB = -1;
+               next = waveCbPOadr(chainGetCB(cb));
 
-                     p->next = waveCbPOadr(counters * CBS_PER_OPAGE);
+               /* dummy src and dest */
+               p->info = NORMAL_DMA;
+               p->src = (uint32_t) (&dmaOBus[0]->periphData);
+               p->dst = (uint32_t) (&dmaOBus[0]->periphData);
+               p->length = 4;
+               p->next = waveCbPOadr(chainGetCntCB(counters));
 
-                     counters++;
-                  }
-                  else SOFT_ERROR(PI_BAD_REPEAT_CNT,
-                          "bad chain repeat count (%d)", cycles);
+               chainMakeCounter(counters, blklen, blocks,
+                            cycles-1, repeat, next);
+
+               counters++;
+            }
+            loop = -1;
+         }
+         else if (cmd == 2) /* delay us */
+         {
+            if ((i+4) > bufSize)
+               SOFT_ERROR(PI_BAD_CHAIN_CMD,
+                  "incomplete chain command (at %d)", i);
+
+            cycles = ((unsigned)buf[i+3] <<  8) + (unsigned)buf[i+2];
+
+            i += 4;
+
+            if (cycles > PI_MAX_WAVE_DELAY)
+               SOFT_ERROR(PI_BAD_CHAIN_DELAY,
+                  "bad chain delay micros (%d)", cycles);
+
+            if (cycles)
+            {
+               chaincb = chainGetCB(cb++);
+
+               if (chaincb < 0)
+                  SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
+
+               p = rawWaveCBAdr(chaincb);
+
+               /* use the secondary clock */
+
+               if (gpioCfg.clockPeriph != PI_CLOCK_PCM)
+               {
+                  p->info = NORMAL_DMA | TIMED_DMA(2);
+                  p->dst  = PCM_TIMER;
                }
-               else SOFT_ERROR(PI_BAD_REPEAT_WID,
-                       "bad chain repeat wave (%d)", rwid);
+               else
+               {
+                  p->info = NORMAL_DMA | TIMED_DMA(5);
+                  p->dst  = PWM_TIMER;
+               }
+
+               p->src    = (uint32_t) (&dmaOBus[0]->periphData);
+               p->length = 4 * cycles / PI_WF_MICROS;
+               p->next   = waveCbPOadr(chainGetCB(cb));
             }
-            else SOFT_ERROR(PI_BAD_CHAIN_CMD,
-                    "bad chain command (at char %d)", i);
          }
-         else SOFT_ERROR(PI_TOO_MANY_COUNTS,
-                 "too many chain counters (at char %d)", i);
+         else
+            SOFT_ERROR(PI_BAD_CHAIN_CMD,
+               "unknown chain command (255 %d)", cmd);
       }
-      else if (wid >= waveOutCount)
+      else if ((wid >= waveOutCount) || waveInfo[wid].deleted)
          SOFT_ERROR(PI_BAD_WAVE_ID, "undefined wave (%d)", wid);
       else
       {
-         if (used[wid] == 255)
-         {
-            used[wid] = counters;
+         chaincb = chainGetCB(cb++);
 
-            if (firstCB < 0) firstCB = waveInfo[wid].botCB;
+         if (chaincb < 0)
+            SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
 
-            if (lastCB >= 0)
-            {
-               p = rawWaveCBAdr(lastCB);
+         p = rawWaveCBAdr(chaincb);
 
-               p->next = waveCbPOadr(1+waveInfo[wid].botCB);
-            }
-            lastCB = waveInfo[wid].topCB;
-         }
-         else SOFT_ERROR(PI_REUSED_WID,
-                 "wave already used in chain (%d)", wid);
+         chaincb = chainGetCB(cb);
+
+         if (chaincb < 0)
+            SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
+
+         chainSetVal(cb-1, waveCbPOadr(chaincb));
+
+         /* patch next of wid topCB to next cb */
+
+         p->info   = NORMAL_DMA;
+         p->src    = chainGetValPadr(cb-1); /* this next */
+         p->dst    = waveCbPOadr(waveInfo[wid].topCB) + 20; /* wid next */
+         p->length = 4;
+         p->next   = waveCbPOadr(waveInfo[wid].botCB+1);
+
+         i += 1;
       }
-      i++;
    }
 
-   if (firstCB >= 0)
-   {
-      if (lastCB >= 0)
-      {
-         p = rawWaveCBAdr(lastCB);
+   chaincb = chainGetCB(cb++);
 
-         p->next = 0;
-      }
+   if (chaincb < 0)
+      SOFT_ERROR(PI_CHAIN_TOO_BIG, "chain is too long (%d)", cb);
 
-      initDMAgo((uint32_t *)dmaOut, waveCbPOadr(firstCB));
-   }
+   p = rawWaveCBAdr(chaincb);
+
+   p->info   = NORMAL_DMA;
+   p->src    = (uint32_t) (&dmaOBus[0]->periphData);
+   p->dst    = (uint32_t) (&dmaOBus[0]->periphData);
+   p->length = 4;
+   p->next = 0;
+
+   initDMAgo((uint32_t *)dmaOut, waveCbPOadr(chainGetCB(0)));
 
    return 0;
 }
index f5f12a6f7c67b01f95b67135dd8d8f8bd58d0af7..a13d3be395eec4855a130e0446fc34d0dc610c5f 100644 (file)
--- a/pigpio.h
+++ b/pigpio.h
@@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
 #include <stdint.h>
 #include <pthread.h>
 
-#define PIGPIO_VERSION 34
+#define PIGPIO_VERSION 35
 
 /*TEXT
 
@@ -197,7 +197,7 @@ gpioWaveAddGeneric         Adds a series of pulses to the waveform
 gpioWaveAddSerial          Adds serial data to the waveform
 
 gpioWaveCreate             Creates a waveform from added data
-gpioWaveDelete             Deletes one or more waveforms
+gpioWaveDelete             Deletes a waveform
 
 gpioWaveTxSend             Transmits a waveform
 
@@ -218,8 +218,6 @@ gpioWaveGetCbs             Length in control blocks of the current waveform
 gpioWaveGetHighCbs         Length of longest waveform so far
 gpioWaveGetMaxCbs          Absolute maximum allowed control blocks
 
-gpioWaveTxStart            Creates/transmits a waveform (DEPRECATED)
-
 I2C
 
 i2cOpen                    Opens an I2C device
@@ -383,12 +381,31 @@ typedef struct
    uint32_t flags;
 } rawWave_t;
 
+/*
+CBs are used in order from the lowest numbered CB up to
+the maximum NUM_WAVE_CBS.
+
+OOLS are used from the bottom climbing up and from
+the top climbing down.
+
+The gpio on and off settings climb up from the bottom (botOOL/numBOOL).
+
+The level and tick read values are stored in descending locations
+from the top (topOOL/numTOOL).
+*/
+
 typedef struct
 {
    uint16_t botCB;  /* first CB used by wave  */
    uint16_t topCB;  /* last CB used by wave   */
-   uint16_t botOOL; /* last OOL used by wave  */
-   uint16_t topOOL; /* first OOL used by wave */
+   uint16_t botOOL; /* first bottom OOL used by wave  */
+                    /* botOOL to botOOL + numBOOL -1 are in use */
+   uint16_t topOOL; /* last top OOL used by wave */
+                    /* topOOL - numTOOL to topOOL are in use.*/
+   uint16_t deleted;
+   uint16_t numCB;
+   uint16_t numBOOL;
+   uint16_t numTOOL;
 } rawWaveInfo_t;
 
 typedef struct
@@ -549,10 +566,12 @@ typedef void *(gpioThreadFunc_t) (void *);
 
 #define PI_WAVE_MAX_MICROS (30 * 60 * 1000000) /* half an hour */
 
-#define PI_MAX_WAVES       250
-//#define PI_MAX_WAVE_CYCLES 537824
-#define PI_MAX_WAVE_CYCLES 16777216
-#define PI_WAVE_COUNTERS   5
+#define PI_MAX_WAVES 250
+
+#define PI_MAX_WAVE_CYCLES 65535
+#define PI_MAX_WAVE_DELAY  65535
+
+#define PI_WAVE_COUNT_PAGES 10
 
 /* wave tx mode */
 
@@ -1511,8 +1530,9 @@ D*/
 int gpioWaveCreate(void);
 /*D
 This function creates a waveform from the data provided by the prior
-calls to the [*gpioWaveAdd**] functions.  Upon success a positive wave id
-is returned.
+calls to the [*gpioWaveAdd**] functions.  Upon success a wave id
+greater than or equal to 0 is returned, otherwise PI_EMPTY_WAVEFORM,
+PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
 
 The data provided by the [*gpioWaveAdd**] functions is consumed by this
 function.
@@ -1564,8 +1584,7 @@ D*/
 /*F*/
 int gpioWaveDelete(unsigned wave_id);
 /*D
-This function deletes all created waveforms with ids greater than or
-equal to wave_id.
+This function deletes the waveform with id wave_id.
 
 . .
 wave_id: >=0, as returned by [*gpioWaveCreate*]
@@ -1577,26 +1596,6 @@ Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
 D*/
 
 
-/*F*/
-int gpioWaveTxStart(unsigned wave_mode); /* DEPRECATED */
-/*D
-This function creates and then transmits a waveform.  The mode
-determines whether the waveform is sent once or cycles endlessly.
-
-NOTE: Any hardware PWM started by [*gpioHardwarePWM*] will be cancelled.
-
-. .
-wave_mode: 0 (PI_WAVE_MODE_ONE_SHOT), 1 (PI_WAVE_MODE_REPEAT)
-. .
-
-This function is deprecated and should no longer be used.  Use
-[*gpioWaveCreate*] and [*gpioWaveTxSend*] instead.
-
-Returns the number of DMA control blocks in the waveform if OK,
-otherwise PI_BAD_WAVE_MODE.
-D*/
-
-
 /*F*/
 int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode);
 /*D
@@ -1623,7 +1622,7 @@ This function transmits a chain of waveforms.
 NOTE: Any hardware PWM started by [*gpioHardwarePWM*] will be cancelled.
 
 The waves to be transmitted are specified by the contents of buf
-which contains an ordered list of wave_ids and optional command
+which contains an ordered list of [*wave_id*]s and optional command
 codes and related data.
 
 . .
@@ -1631,51 +1630,81 @@ codes and related data.
 bufSize: the number of bytes in buf
 . .
 
-Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
-PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+Returns 0 if OK, otherwise PI_CHAIN_NESTING, PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD, PI_CHAIN_COUNTER,
+PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG, or PI_BAD_WAVE_ID.
 
-Each wave is transmitted in the order specified.  A wave may only
-occur once per chain.  Waves may be transmitted multiple times by
-using the repeat command.  The repeat command specifies a wave id
-and a count.  The wave id must occur earlier in the chain.  All the
-waves between wave id and the repeat command are transmitted count
-times.
+Each wave is transmitted in the order specified.  A wave may
+occur multiple times per chain.
 
-Repeat commands may not be nested.  The minimum repeat count is 2.
-A maximum of 5 repeat commands is supported per chain.
+A blocks of waves may be transmitted multiple times by using
+the loop commands. The block is bracketed by loop start and
+end commands.  Loops may be nested.
+
+Delays between waves may be added with the delay command.
 
 The following command codes are supported:
 
-Name    @ Cmd & Data       @ Meaning
-Repeat  @ 255 wid C0 C1 C2 @ Repeat from wid count times
-count = C0 + C1*256 + C2*65536
+Name        @ Cmd & Data @ Meaning
+Loop Start  @ 255 0      @ Identify start of a wave block
+Loop Repeat @ 255 1 x y  @ loop x + y*256 times
+Delay       @ 255 2 x y  @ delay x + y*256 microseconds
+
+The code is currently dimensioned to support a chain with roughly
+600 entries and 20 loop counters.
 
 ...
-The following examples assume that waves with ids 0 to 12 exist.
+#include <stdio.h>
+#include <pigpio.h>
+
+#define WAVES 5
+#define GPIO 4
+
+int main(int argc, char *argv[])
+{
+   int i, wid[WAVES];
+
+   if (gpioInitialise()<0) return -1;
+
+   gpioSetMode(GPIO, PI_OUTPUT);
+
+   printf("start piscope, press return\n"); getchar();
+
+   for (i=0; i<WAVES; i++)
+   {
+      gpioWaveAddGeneric(2, (gpioPulse_t[])
+         {{1<<GPIO, 0,        20},
+          {0, 1<<GPIO, (i+1)*200}});
+
+      wid[i] = gpioWaveCreate();
+   }
 
-// 0 255 0 57 0 0 (repeat 0 57 times)
-status = gpioWaveChain((char []){0, 255, 0, 57, 0, 0}, 6);
+   gpioWaveChain((char []) {
+      wid[4], wid[3], wid[2],       // transmit waves 4+3+2
+      255, 0,                       // loop start
+         wid[0], wid[0], wid[0],    // transmit waves 0+0+0
+         255, 0,                    // loop start
+            wid[0], wid[1],         // transmit waves 0+1
+            255, 2, 0x88, 0x13,     // delay 5000us
+         255, 1, 30, 0,             // loop end (repeat 30 times)
+         255, 0,                    // loop start
+            wid[2], wid[3], wid[0], // transmit waves 2+3+0
+            wid[3], wid[1], wid[2], // transmit waves 3+1+2
+         255, 1, 10, 0,             // loop end (repeat 10 times)
+      255, 1, 5, 0,                 // loop end (repeat 5 times)
+      wid[4], wid[4], wid[4],       // transmit waves 4+4+4
+      255, 2, 0x20, 0x4E,           // delay 20000us
+      wid[0], wid[0], wid[0],       // transmit waves 0+0+0
 
-// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
-status = gpioWaveChain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+      }, 46);
 
-// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
-status = gpioWaveChain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+   while (gpioWaveTxBusy()) time_sleep(0.1);
 
-// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
-status = gpioWaveChain(
-   (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+   for (i=0; i<WAVES; i++) gpioWaveDelete(wid[i]);
 
-// The following repeats 5 65793 times, transmits 6,
-// repeats 7+8 514 times, transmits 12,
-// repeats 9+11+10 197121 times.
-// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
-char chain[] = {
-   5,             255, 5, 1, 1, 1,
-   6, 7, 8,       255, 7, 2, 2, 0,
-   12, 9, 11, 10, 255, 9, 1, 2, 3};
+   printf("stop piscope, press return\n"); getchar();
 
-status = gpioWaveChain(chain, sizeof(chain));
+   gpioTerminate();
+}
 ...
 D*/
 
@@ -3135,8 +3164,8 @@ int gpioHardwarePWM(unsigned gpio, unsigned PWMfreq, unsigned PWMduty);
 Starts hardware PWM on a gpio at the specified frequency and dutycycle.
 Frequencies above 30MHz are unlikely to work.
 
-NOTE: Any waveform started by [*gpioWaveTxSend*], [*gpioWaveTxStart*],
-or [*gpioWaveChain*] will be cancelled.
+NOTE: Any waveform started by [*gpioWaveTxSend*], or
+[*gpioWaveChain*] will be cancelled.
 
 This function is only valid if the pigpio main clock is PCM.  The
 main clock defaults to PCM but may be overridden by a call to
@@ -4428,7 +4457,7 @@ Denoting no parameter is required
 
 wave_id::
 
-A number representing a waveform created by [*gpioWaveCreate*].
+A number identifying a waveform created by [*gpioWaveCreate*].
 
 wave_mode::
 
@@ -4729,11 +4758,14 @@ after this command is issued.
 #define PI_BAD_I2C_RLEN    -110 // bad I2C read length
 #define PI_BAD_I2C_CMD     -111 // bad I2C command
 #define PI_BAD_I2C_BAUD    -112 // bad I2C baud rate, not 50-500k
-#define PI_BAD_REPEAT_CNT  -113 // bad repeat count, not 2-max
-#define PI_BAD_REPEAT_WID  -114 // bad repeat wave id
-#define PI_TOO_MANY_COUNTS -115 // too many chain counters
-#define PI_BAD_CHAIN_CMD   -116 // malformed chain command string
-#define PI_REUSED_WID      -117 // wave already used in chain
+#define PI_CHAIN_LOOP_CNT  -113 // bad chain loop count
+#define PI_BAD_CHAIN_LOOP  -114 // empty chain loop
+#define PI_CHAIN_COUNTER   -115 // too many chain counters
+#define PI_BAD_CHAIN_CMD   -116 // bad chain command
+#define PI_BAD_CHAIN_DELAY -117 // bad chain delay micros
+#define PI_CHAIN_NESTING   -118 // chain counters nested too deeply
+#define PI_CHAIN_TOO_BIG   -119 // chain is too long
+#define PI_DEPRECATED      -120 // deprecated function removed
 
 #define PI_PIGIF_ERR_0    -2000
 #define PI_PIGIF_ERR_99   -2099
index 9a321f669cc05d544c52c633a131012f4a1cef79..28bff0892bd5ec46f55522fe42bc84ec799372a3 100644 (file)
--- a/pigpio.py
+++ b/pigpio.py
@@ -182,9 +182,6 @@ wave_chain                Transmits a chain of waveforms
 wave_tx_busy              Checks to see if a waveform has ended
 wave_tx_stop              Aborts the current waveform
 
-wave_tx_repeat            Creates/transmits a waveform (DEPRECATED)
-wave_tx_start             Creates/transmits a waveform (DEPRECATED)
-
 wave_get_micros           Length in microseconds of the current waveform
 wave_get_max_micros       Absolute maximum allowed micros
 wave_get_pulses           Length in pulses of the current waveform
@@ -266,7 +263,7 @@ import threading
 import os
 import atexit
 
-VERSION = "1.19"
+VERSION = "1.20"
 
 exceptions = True
 
@@ -550,11 +547,14 @@ PI_BAD_I2C_WLEN     =-109
 PI_BAD_I2C_RLEN     =-110
 PI_BAD_I2C_CMD      =-111
 PI_BAD_I2C_BAUD     =-112
-PI_BAD_REPEAT_CNT   =-113
-PI_BAD_REPEAT_WID   =-114
-PI_TOO_MANY_COUNTS  =-115
+PI_CHAIN_LOOP_CNT   =-113
+PI_BAD_CHAIN_LOOP   =-114
+PI_CHAIN_COUNTER    =-115
 PI_BAD_CHAIN_CMD    =-116
-PI_REUSED_WID       =-117
+PI_BAD_CHAIN_DELAY  =-117
+PI_CHAIN_NESTING    =-118
+PI_CHAIN_TOO_BIG    =-119
+PI_DEPRECATED       =-120
 
 # pigpio error text
 
@@ -669,11 +669,14 @@ _errors=[
    [PI_BAD_I2C_RLEN      , "bad I2C read length"],
    [PI_BAD_I2C_CMD       , "bad I2C command"],
    [PI_BAD_I2C_BAUD      , "bad I2C baud rate, not 50-500k"],
-   [PI_BAD_REPEAT_CNT    , "bad repeat count, not 2-max"],
-   [PI_BAD_REPEAT_WID    , "bad repeat wave id"],
-   [PI_TOO_MANY_COUNTS   , "too many chain counters"],
-   [PI_BAD_CHAIN_CMD     , "malformed chain command string"],
-   [PI_REUSED_WID        , "wave already used in chain"],
+   [PI_CHAIN_LOOP_CNT    , "bad chain loop count"],
+   [PI_BAD_CHAIN_LOOP    , "empty chain loop"],
+   [PI_CHAIN_COUNTER     , "too many chain counters"],
+   [PI_BAD_CHAIN_CMD     , "bad chain command"],
+   [PI_BAD_CHAIN_DELAY   , "bad chain delay micros"],
+   [PI_CHAIN_NESTING     , "chain counters nested too deeply"],
+   [PI_CHAIN_TOO_BIG     , "chain is too long"],
+   [PI_DEPRECATED        , "deprecated function removed"],
 
 ]
 
@@ -1551,8 +1554,7 @@ class pi():
       and dutycycle. Frequencies above 30MHz are unlikely to work.
 
       NOTE: Any waveform started by [*wave_send_once*],
-      [*wave_send_repeat*], [*wave_tx_start*], [*wave_tx_repeat*],
-      or [*wave_chain*] will be cancelled.
+      [*wave_send_repeat*], or [*wave_chain*] will be cancelled.
 
       This function is only valid if the pigpio main clock is PCM.
       The main clock defaults to PCM but may be overridden when the
@@ -1821,7 +1823,8 @@ class pi():
       Creates a waveform from the data provided by the prior calls
       to the [*wave_add_**] functions.
 
-      Returns a wave id (>=0) if OK.
+      Returns a wave id (>=0) if OK,  otherwise PI_EMPTY_WAVEFORM,
+      PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
 
       The data provided by the [*wave_add_**] functions is consumed by
       this function.
@@ -1864,40 +1867,33 @@ class pi():
 
    def wave_delete(self, wave_id):
       """
-      Deletes all created waveforms with ids greater than or equal
-      to wave_id.
+      This function deletes the waveform with id wave_id.
 
       wave_id:= >=0 (as returned by a prior call to [*wave_create*]).
 
       Wave ids are allocated in order, 0, 1, 2, etc.
 
       ...
-      pi.wave_delete(6) # delete all waves with id 6 or greater
+      pi.wave_delete(6) # delete waveform with id 6
 
-      pi.wave_delete(0) # delete all waves
+      pi.wave_delete(0) # delete waveform with id 0
       ...
       """
       return _u2i(_pigpio_command(self.sl, _PI_CMD_WVDEL, wave_id, 0))
 
    def wave_tx_start(self): # DEPRECATED
       """
-      This function is deprecated and will be removed.
+      This function is deprecated and has been removed.
 
       Use [*wave_create*]/[*wave_send_**] instead.
-
-      NOTE: Any hardware PWM started by [*hardware_PWM*] will
-      be cancelled.
       """
       return _u2i(_pigpio_command(self.sl, _PI_CMD_WVGO, 0, 0))
 
    def wave_tx_repeat(self): # DEPRECATED
       """
-      This function is deprecated and will be removed.
+      This function is deprecated and has beeen removed.
 
       Use [*wave_create*]/[*wave_send_**] instead.
-
-      NOTE: Any hardware PWM started by [*hardware_PWM*] will
-      be cancelled.
       """
       return _u2i(_pigpio_command(self.sl, _PI_CMD_WVGOR, 0, 0))
 
@@ -1975,58 +1971,84 @@ class pi():
       """
       This function transmits a chain of waveforms.
 
-      NOTE: Any hardware PWM started by [*hardware_PWM*] will
-      be cancelled.
+      NOTE: Any hardware PWM started by [*hardware_PWM*]
+      will be cancelled.
 
-      The waves to be transmitted are specified by the contents of
-      data which contains an ordered list of wave_ids and optional
-      command codes and related data.
+      The waves to be transmitted are specified by the contents
+      of data which contains an ordered list of [*wave_id*]s
+      and optional command codes and related data.
 
-      data:= contains the wave_ids and optional command codes
+      Returns 0 if OK, otherwise PI_CHAIN_NESTING,
+      PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD,
+      PI_CHAIN_COUNTER, PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG,
+      or PI_BAD_WAVE_ID.
 
-      Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
-      PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+      Each wave is transmitted in the order specified.  A wave
+      may occur multiple times per chain.
 
-      Each wave is transmitted in the order specified.  A wave may
-      only occur once per chain.  Waves may be transmitted multiple
-      times by using the repeat command.  The repeat command
-      specifies a wave id and a count.  The wave id must occur
-      earlier in the chain.  All the waves between wave id and the
-      repeat command are transmitted count times.
+      A blocks of waves may be transmitted multiple times by
+      using the loop commands. The block is bracketed by loop
+      start and end commands.  Loops may be nested.
 
-      Repeat commands may not be nested.  The minimum repeat
-      count is 2. A maximum of 5 repeat commands is supported
-      per chain.
+      Delays between waves may be added with the delay command.
 
       The following command codes are supported:
 
-      Name    @ Cmd & Data       @ Meaning
-      Repeat  @ 255 wid C0 C1 C2 @ Repeat from wid count times
-      count = C0 + C1*256 + C2*65536
+      Name        @ Cmd & Data @ Meaning
+      Loop Start  @ 255 0      @ Identify start of a wave block
+      Loop Repeat @ 255 1 x y  @ loop x + y*256 times
+      Delay       @ 255 2 x y  @ delay x + y*256 microseconds
+
+      The code is currently dimensioned to support a chain with
+      roughly 600 entries and 20 loop counters.
 
       ...
-      The following examples assume that waves with ids 0 to 12 exist.
+      #!/usr/bin/env python
+
+      import time
+      import pigpio
+
+      WAVES=5
+      GPIO=4
 
-      # 0 255 0 57 0 0 (repeat 0 57 times)
-      pi.wave_chain([0, 255, 0, 57, 0, 0])
+      wid=[0]*WAVES
 
-      # 0 1 255 0 0 2 0 (repeat 0+1 512 times)
-      pi.wave_chain([0, 1, 255, 0, 0, 2, 0])
+      pi = pigpio.pi() # Connect to local Pi.
 
-      # 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
-      pi.wave_chain([0, 1, 255, 1, 0, 0, 1])
+      pi.set_mode(GPIO, pigpio.OUTPUT);
 
-      # 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
-      pi.wave_chain([0, 1, 2, 3, 255, 2, 13, 0, 0])
+      for i in range(WAVES):
+         pi.wave_add_generic([
+            pigpio.pulse(1<<GPIO, 0, 20),
+            pigpio.pulse(0, 1<<GPIO, (i+1)*200)]);
+
+         wid[i] = pi.wave_create();
 
-      # The following repeats 5 65793 times, transmits 6,
-      # repeats 7+8 514 times, transmits 12,
-      # repeats 9+11+10 197121 times.
-      # 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
       pi.wave_chain([
-         5,             255, 5, 1, 1, 1,
-         6, 7, 8,       255, 7, 2, 2, 0,
-         12, 9, 11, 10, 255, 9, 1, 2, 3])
+         wid[4], wid[3], wid[2],       # transmit waves 4+3+2
+         255, 0,                       # loop start
+            wid[0], wid[0], wid[0],    # transmit waves 0+0+0
+            255, 0,                    # loop start
+               wid[0], wid[1],         # transmit waves 0+1
+               255, 2, 0x88, 0x13,     # delay 5000us
+            255, 1, 30, 0,             # loop end (repeat 30 times)
+            255, 0,                    # loop start
+               wid[2], wid[3], wid[0], # transmit waves 2+3+0
+               wid[3], wid[1], wid[2], # transmit waves 3+1+2
+            255, 1, 10, 0,             # loop end (repeat 10 times)
+         255, 1, 5, 0,                 # loop end (repeat 5 times)
+         wid[4], wid[4], wid[4],       # transmit waves 4+4+4
+         255, 2, 0x20, 0x4E,           # delay 20000us
+         wid[0], wid[0], wid[0],       # transmit waves 0+0+0
+         ])
+
+      while pi.wave_tx_busy():
+         time.sleep(0.1);
+
+      for i in range(WAVES):
+         pi.wave_delete(wid[i])
+
+      pi.stop()
       ...
       """
       # I p1 0
@@ -3386,12 +3408,18 @@ class pi():
            edge:= EITHER_EDGE, RISING_EDGE (default), or FALLING_EDGE.
            func:= user supplied callback function.
 
-      If a user callback is not specified a default tally callback is
-      provided which simply counts edges.
-
       The user supplied callback receives three parameters, the gpio,
       the level, and the tick.
 
+      If a user callback is not specified a default tally callback is
+      provided which simply counts edges.  The count may be retrieved
+      by calling the tally function.
+
+      The callback may be cancelled by calling the cancel function.
+
+      A gpio may have multiple callbacks (although I can't think of
+      a reason to do so).
+
       ...
       def cbf(gpio, level, tick):
          print(gpio, level, tick)
@@ -3403,6 +3431,8 @@ class pi():
       cb3 = pi.callback(17)
 
       print(cb3.tally())
+
+      cb1.cancel() # To cancel callback cb1.
       ...
       """
       return _callback(self._notify, user_gpio, edge, func)
@@ -3594,96 +3624,100 @@ def xref():
    RISING_EDGE = 0
 
    errnum: <0
+
    . .
-   PI_BAD_USER_GPIO    =-2
-   PI_BAD_GPIO         =-3
-   PI_BAD_MODE         =-4
-   PI_BAD_LEVEL        =-5
-   PI_BAD_PUD          =-6
-   PI_BAD_PULSEWIDTH   =-7
-   PI_BAD_DUTYCYCLE    =-8
-   PI_BAD_WDOG_TIMEOUT =-15
-   PI_BAD_DUTYRANGE    =-21
-   PI_NO_HANDLE        =-24
-   PI_BAD_HANDLE       =-25
-   PI_BAD_WAVE_BAUD    =-35
-   PI_TOO_MANY_PULSES  =-36
-   PI_TOO_MANY_CHARS   =-37
-   PI_NOT_SERIAL_GPIO  =-38
-   PI_NOT_PERMITTED    =-41
-   PI_SOME_PERMITTED   =-42
-   PI_BAD_WVSC_COMMND  =-43
-   PI_BAD_WVSM_COMMND  =-44
-   PI_BAD_WVSP_COMMND  =-45
-   PI_BAD_PULSELEN     =-46
-   PI_BAD_SCRIPT       =-47
-   PI_BAD_SCRIPT_ID    =-48
-   PI_BAD_SER_OFFSET   =-49
-   PI_GPIO_IN_USE      =-50
-   PI_BAD_SERIAL_COUNT =-51
-   PI_BAD_PARAM_NUM    =-52
-   PI_DUP_TAG          =-53
-   PI_TOO_MANY_TAGS    =-54
-   PI_BAD_SCRIPT_CMD   =-55
-   PI_BAD_VAR_NUM      =-56
-   PI_NO_SCRIPT_ROOM   =-57
-   PI_NO_MEMORY        =-58
-   PI_SOCK_READ_FAILED =-59
-   PI_SOCK_WRIT_FAILED =-60
-   PI_TOO_MANY_PARAM   =-61
-   PI_NOT_HALTED       =-62
-   PI_BAD_TAG          =-63
-   PI_BAD_MICS_DELAY   =-64
-   PI_BAD_MILS_DELAY   =-65
-   PI_BAD_WAVE_ID      =-66
-   PI_TOO_MANY_CBS     =-67
-   PI_TOO_MANY_OOL     =-68
-   PI_EMPTY_WAVEFORM   =-69
-   PI_NO_WAVEFORM_ID   =-70
-   PI_I2C_OPEN_FAILED  =-71
-   PI_SER_OPEN_FAILED  =-72
-   PI_SPI_OPEN_FAILED  =-73
-   PI_BAD_I2C_BUS      =-74
-   PI_BAD_I2C_ADDR     =-75
-   PI_BAD_SPI_CHANNEL  =-76
-   PI_BAD_FLAGS        =-77
-   PI_BAD_SPI_SPEED    =-78
-   PI_BAD_SER_DEVICE   =-79
-   PI_BAD_SER_SPEED    =-80
-   PI_BAD_PARAM        =-81
-   PI_I2C_WRITE_FAILED =-82
-   PI_I2C_READ_FAILED  =-83
-   PI_BAD_SPI_COUNT    =-84
-   PI_SER_WRITE_FAILED =-85
-   PI_SER_READ_FAILED  =-86
-   PI_SER_READ_NO_DATA =-87
-   PI_UNKNOWN_COMMAND  =-88
-   PI_SPI_XFER_FAILED  =-89
-   PI_NO_AUX_SPI       =-91
-   PI_NOT_PWM_GPIO     =-92
-   PI_NOT_SERVO_GPIO   =-93
-   PI_NOT_HCLK_GPIO    =-94
-   PI_NOT_HPWM_GPIO    =-95
-   PI_BAD_HPWM_FREQ    =-96
-   PI_BAD_HPWM_DUTY    =-97
-   PI_BAD_HCLK_FREQ    =-98
-   PI_BAD_HCLK_PASS    =-99
-   PI_HPWM_ILLEGAL     =-100
-   PI_BAD_DATABITS     =-101
-   PI_BAD_STOPBITS     =-102
-   PI_MSG_TOOBIG       =-103
-   PI_BAD_MALLOC_MODE  =-104
-   PI_BAD_SMBUS_CMD    =-107
-   PI_NOT_I2C_GPIO     =-108
-   PI_BAD_I2C_WLEN     =-109
-   PI_BAD_I2C_RLEN     =-110
-   PI_BAD_I2C_CMD      =-111
-   PI_BAD_I2C_BAUD     =-112
-   PI_BAD_REPEAT_CNT   =-113
-   PI_BAD_REPEAT_WID   =-114
-   PI_TOO_MANY_COUNTS  =-115
-   PI_BAD_CHAIN_CMD    =-116
-   PI_REUSED_WID       =-117
+   PI_BAD_USER_GPIO = -2
+   PI_BAD_GPIO = -3
+   PI_BAD_MODE = -4
+   PI_BAD_LEVEL = -5
+   PI_BAD_PUD = -6
+   PI_BAD_PULSEWIDTH = -7
+   PI_BAD_DUTYCYCLE = -8
+   PI_BAD_WDOG_TIMEOUT = -15
+   PI_BAD_DUTYRANGE = -21
+   PI_NO_HANDLE = -24
+   PI_BAD_HANDLE = -25
+   PI_BAD_WAVE_BAUD = -35
+   PI_TOO_MANY_PULSES = -36
+   PI_TOO_MANY_CHARS = -37
+   PI_NOT_SERIAL_GPIO = -38
+   PI_NOT_PERMITTED = -41
+   PI_SOME_PERMITTED = -42
+   PI_BAD_WVSC_COMMND = -43
+   PI_BAD_WVSM_COMMND = -44
+   PI_BAD_WVSP_COMMND = -45
+   PI_BAD_PULSELEN = -46
+   PI_BAD_SCRIPT = -47
+   PI_BAD_SCRIPT_ID = -48
+   PI_BAD_SER_OFFSET = -49
+   PI_GPIO_IN_USE = -50
+   PI_BAD_SERIAL_COUNT = -51
+   PI_BAD_PARAM_NUM = -52
+   PI_DUP_TAG = -53
+   PI_TOO_MANY_TAGS = -54
+   PI_BAD_SCRIPT_CMD = -55
+   PI_BAD_VAR_NUM = -56
+   PI_NO_SCRIPT_ROOM = -57
+   PI_NO_MEMORY = -58
+   PI_SOCK_READ_FAILED = -59
+   PI_SOCK_WRIT_FAILED = -60
+   PI_TOO_MANY_PARAM = -61
+   PI_NOT_HALTED = -62
+   PI_BAD_TAG = -63
+   PI_BAD_MICS_DELAY = -64
+   PI_BAD_MILS_DELAY = -65
+   PI_BAD_WAVE_ID = -66
+   PI_TOO_MANY_CBS = -67
+   PI_TOO_MANY_OOL = -68
+   PI_EMPTY_WAVEFORM = -69
+   PI_NO_WAVEFORM_ID = -70
+   PI_I2C_OPEN_FAILED = -71
+   PI_SER_OPEN_FAILED = -72
+   PI_SPI_OPEN_FAILED = -73
+   PI_BAD_I2C_BUS = -74
+   PI_BAD_I2C_ADDR = -75
+   PI_BAD_SPI_CHANNEL = -76
+   PI_BAD_FLAGS = -77
+   PI_BAD_SPI_SPEED = -78
+   PI_BAD_SER_DEVICE = -79
+   PI_BAD_SER_SPEED = -80
+   PI_BAD_PARAM = -81
+   PI_I2C_WRITE_FAILED = -82
+   PI_I2C_READ_FAILED = -83
+   PI_BAD_SPI_COUNT = -84
+   PI_SER_WRITE_FAILED = -85
+   PI_SER_READ_FAILED = -86
+   PI_SER_READ_NO_DATA = -87
+   PI_UNKNOWN_COMMAND = -88
+   PI_SPI_XFER_FAILED = -89
+   PI_NO_AUX_SPI = -91
+   PI_NOT_PWM_GPIO = -92
+   PI_NOT_SERVO_GPIO = -93
+   PI_NOT_HCLK_GPIO = -94
+   PI_NOT_HPWM_GPIO = -95
+   PI_BAD_HPWM_FREQ = -96
+   PI_BAD_HPWM_DUTY = -97
+   PI_BAD_HCLK_FREQ = -98
+   PI_BAD_HCLK_PASS = -99
+   PI_HPWM_ILLEGAL = -100
+   PI_BAD_DATABITS = -101
+   PI_BAD_STOPBITS = -102
+   PI_MSG_TOOBIG = -103
+   PI_BAD_MALLOC_MODE = -104
+   PI_BAD_SMBUS_CMD = -107
+   PI_NOT_I2C_GPIO = -108
+   PI_BAD_I2C_WLEN = -109
+   PI_BAD_I2C_RLEN = -110
+   PI_BAD_I2C_CMD = -111
+   PI_BAD_I2C_BAUD = -112
+   PI_CHAIN_LOOP_CNT = -113
+   PI_BAD_CHAIN_LOOP = -114
+   PI_CHAIN_COUNTER = -115
+   PI_BAD_CHAIN_CMD = -116
+   PI_BAD_CHAIN_DELAY = -117
+   PI_CHAIN_NESTING = -118
+   PI_CHAIN_TOO_BIG = -119
+   PI_DEPRECATED = -120
    . .
 
    frequency: 0-40000
index 0bcde27893f912027b29b3210b31c2e6407a50e3..592a4730d609fb9bbc8dafd17da4d8dd9a74d0cd 100644 (file)
@@ -1221,8 +1221,8 @@ Frequencies above 30MHz are unlikely to work.
 .br
 
 .br
-NOTE: Any waveform started by \fBwave_send_once\fP, \fBwave_send_repeat\fP, \fBwave_tx_start\fP, \fBwave_tx_repeat\fP, or \fBwave_chain\fP
-will be cancelled.
+NOTE: Any waveform started by \fBwave_send_once\fP, \fBwave_send_repeat\fP,
+or \fBwave_chain\fP will be cancelled.
 
 .br
 
@@ -1493,8 +1493,9 @@ For \fBdata_bits\fP 17-32 there will be four bytes per character.
 .IP "\fBint wave_create(void)\fP"
 .IP "" 4
 This function creates a waveform from the data provided by the prior
-calls to the \fBwave_add_*\fP functions.  Upon success a positive wave id
-is returned.
+calls to the \fBwave_add_*\fP functions.  Upon success a wave id
+greater than or equal to 0 is returned, otherwise PI_EMPTY_WAVEFORM,
+PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
 
 .br
 
@@ -1599,8 +1600,7 @@ PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
 
 .IP "\fBint wave_delete(unsigned wave_id)\fP"
 .IP "" 4
-This function deletes all created waveforms with ids greater than or
-equal to wave_id.
+This function deletes the waveform with id wave_id.
 
 .br
 
@@ -1622,34 +1622,6 @@ Wave ids are allocated in order, 0, 1, 2, etc.
 .br
 Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
 
-.IP "\fBint wave_tx_start(void)\fP"
-.IP "" 4
-This function is deprecated and should no longer be used.
-
-.br
-
-.br
-Use \fBwave_create\fP/\fBwave_send_*\fP instead.
-
-.br
-
-.br
-NOTE: Any hardware PWM started by \fBhardware_PWM\fP will be cancelled.
-
-.IP "\fBint wave_tx_repeat(void)\fP"
-.IP "" 4
-This function is deprecated and should no longer be used.
-
-.br
-
-.br
-Use \fBwave_create\fP/\fBwave_send_*\fP instead.
-
-.br
-
-.br
-NOTE: Any hardware PWM started by \fBhardware_PWM\fP will be cancelled.
-
 .IP "\fBint wave_send_once(unsigned wave_id)\fP"
 .IP "" 4
 This function transmits the waveform with id wave_id.  The waveform
@@ -1716,7 +1688,7 @@ NOTE: Any hardware PWM started by \fBhardware_PWM\fP will be cancelled.
 
 .br
 The waves to be transmitted are specified by the contents of buf
-which contains an ordered list of wave_ids and optional command
+which contains an ordered list of \fBwave_id\fPs and optional command
 codes and related data.
 
 .br
@@ -1734,24 +1706,26 @@ bufSize: the number of bytes in buf
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
-PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
+Returns 0 if OK, otherwise PI_CHAIN_NESTING, PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD, PI_CHAIN_COUNTER,
+PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG, or PI_BAD_WAVE_ID.
+
+.br
 
 .br
+Each wave is transmitted in the order specified.  A wave may
+occur multiple times per chain.
 
 .br
-Each wave is transmitted in the order specified.  A wave may only
-occur once per chain.  Waves may be transmitted multiple times by
-using the repeat command.  The repeat command specifies a wave id
-and a count.  The wave id must occur earlier in the chain.  All the
-waves between wave id and the repeat command are transmitted count
-times.
 
 .br
+A blocks of waves may be transmitted multiple times by using
+the loop commands. The block is bracketed by loop start and
+end commands.  Loops may be nested.
 
 .br
-Repeat commands may not be nested.  The minimum repeat count is 2.
-A maximum of 5 repeat commands is supported per chain.
+
+.br
+Delays between waves may be added with the delay command.
 
 .br
 
@@ -1761,13 +1735,24 @@ The following command codes are supported:
 .br
 
 .br
-Name      Cmd & Data         Meaning
+Name          Cmd & Data   Meaning
+
+.br
+Loop Start    255 0        Identify start of a wave block
+
+.br
+Loop Repeat   255 1 x y    loop x + y*256 times
+
+.br
+Delay         255 2 x y    delay x + y*256 microseconds
 
 .br
-Repeat    255 wid C0 C1 C2   Repeat from wid count times
 
 .br
-count = C0 + C1*256 + C2*65536
+
+.br
+The code is currently dimensioned to support a chain with roughly
+600 entries and 20 loop counters.
 
 .br
 
@@ -1776,55 +1761,101 @@ count = C0 + C1*256 + C2*65536
 .br
 
 .EX
-The following examples assume that waves with ids 0 to 12 exist.
+#include <stdio.h>
+.br
+#include <pigpiod_if.h>
 .br
 
 .br
-// 0 255 0 57 0 0 (repeat 0 57 times)
+#define WAVES 5
 .br
-status = wave_chain((char []){0, 255, 0, 57, 0, 0}, 6);
+#define GPIO 4
 .br
 
 .br
-// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
+int main(int argc, char *argv[])
+.br
+{
 .br
-status = wave_chain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+   int i, wid[WAVES];
 .br
 
 .br
-// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+   if (pigpio_start(0, 0)<0) return -1;
+.br
+
 .br
-status = wave_chain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+   set_mode(GPIO, PI_OUTPUT);
 .br
 
 .br
-// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+   for (i=0; i<WAVES; i++)
+.br
+   {
 .br
-status = wave_chain(
+      wave_add_generic(2, (gpioPulse_t[])
 .br
-   (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+         {{1<<GPIO, 0,        20},
+.br
+          {0, 1<<GPIO, (i+1)*200}});
+.br
+
+.br
+      wid[i] = wave_create();
+.br
+   }
 .br
 
 .br
-// The following repeats 5 65793 times, transmits 6,
+   wave_chain((char []) {
+.br
+      wid[4], wid[3], wid[2],       // transmit waves 4+3+2
+.br
+      255, 0,                       // loop start
+.br
+         wid[0], wid[0], wid[0],    // transmit waves 0+0+0
 .br
-// repeats 7+8 514 times, transmits 12,
+         255, 0,                    // loop start
 .br
-// repeats 9+11+10 197121 times.
+            wid[0], wid[1],         // transmit waves 0+1
 .br
-// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+            255, 2, 0x88, 0x13,     // delay 5000us
 .br
-char chain[] = {
+         255, 1, 30, 0,             // loop end (repeat 30 times)
 .br
-   5,             255, 5, 1, 1, 1,
+         255, 0,                    // loop start
 .br
-   6, 7, 8,       255, 7, 2, 2, 0,
+            wid[2], wid[3], wid[0], // transmit waves 2+3+0
 .br
-   12, 9, 11, 10, 255, 9, 1, 2, 3};
+            wid[3], wid[1], wid[2], // transmit waves 3+1+2
+.br
+         255, 1, 10, 0,             // loop end (repeat 10 times)
+.br
+      255, 1, 5, 0,                 // loop end (repeat 5 times)
+.br
+      wid[4], wid[4], wid[4],       // transmit waves 4+4+4
+.br
+      255, 2, 0x20, 0x4E,           // delay 20000us
+.br
+      wid[0], wid[0], wid[0],       // transmit waves 0+0+0
+.br
+
+.br
+      }, 46);
 .br
 
 .br
-status = wave_chain(chain, sizeof(chain));
+   while (wave_tx_busy()) time_sleep(0.1);
+.br
+
+.br
+   for (i=0; i<WAVES; i++) wave_delete(wid[i]);
+.br
+
+.br
+   pigpio_stop();
+.br
+}
 .br
 
 .EE
index 6e0be8fb04236e8748ccd40c305c83a90c27f8ac..48fa085c3ca9e377aa7883ea2bae6bfd689e67dd 100644 (file)
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 For more information, please refer to <http://unlicense.org/>
 */
 
-/* PIGPIOD_IF_VERSION 16 */
+/* PIGPIOD_IF_VERSION 17 */
 
 #include <stdio.h>
 #include <stdlib.h>
index 5f32ffea92ba082a63dc0aee7d90c09d7da42460..ae96930fd5cbc714d4c4816bed4cb7618850577b 100644 (file)
@@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
 
 #include "pigpio.h"
 
-#define PIGPIOD_IF_VERSION 16
+#define PIGPIOD_IF_VERSION 17
 
 /*TEXT
 
@@ -204,9 +204,6 @@ wave_get_cbs               Length in cbs of the current waveform
 wave_get_high_cbs          Length of longest waveform so far
 wave_get_max_cbs           Absolute maximum allowed cbs
 
-wave_tx_start              Creates/transmits a waveform (DEPRECATED)
-wave_tx_repeat             Creates/transmits a waveform repeatedly (DEPRECATED)
-
 I2C
 
 i2c_open                   Opens an I2C device
@@ -914,8 +911,8 @@ int hardware_PWM(unsigned gpio, unsigned PWMfreq, uint32_t PWMduty);
 Starts hardware PWM on a gpio at the specified frequency and dutycycle.
 Frequencies above 30MHz are unlikely to work.
 
-NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*], [*wave_tx_start*], [*wave_tx_repeat*], or [*wave_chain*]
-will be cancelled.
+NOTE: Any waveform started by [*wave_send_once*], [*wave_send_repeat*],
+or [*wave_chain*] will be cancelled.
 
 This function is only valid if the pigpio main clock is PCM.  The
 main clock defaults to PCM but may be overridden when the pigpio
@@ -1081,8 +1078,9 @@ D*/
 int wave_create(void);
 /*D
 This function creates a waveform from the data provided by the prior
-calls to the [*wave_add_**] functions.  Upon success a positive wave id
-is returned.
+calls to the [*wave_add_**] functions.  Upon success a wave id
+greater than or equal to 0 is returned, otherwise PI_EMPTY_WAVEFORM,
+PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
 
 The data provided by the [*wave_add_**] functions is consumed by this
 function.
@@ -1134,8 +1132,7 @@ D*/
 /*F*/
 int wave_delete(unsigned wave_id);
 /*D
-This function deletes all created waveforms with ids greater than or
-equal to wave_id.
+This function deletes the waveform with id wave_id.
 
 . .
 wave_id: >=0, as returned by [*wave_create*].
@@ -1146,26 +1143,6 @@ Wave ids are allocated in order, 0, 1, 2, etc.
 Returns 0 if OK, otherwise PI_BAD_WAVE_ID.
 D*/
 
-/*F*/
-int wave_tx_start(void);
-/*D
-This function is deprecated and should no longer be used.
-
-Use [*wave_create*]/[*wave_send_**] instead.
-
-NOTE: Any hardware PWM started by [*hardware_PWM*] will be cancelled.
-D*/
-
-/*F*/
-int wave_tx_repeat(void);
-/*D
-This function is deprecated and should no longer be used.
-
-Use [*wave_create*]/[*wave_send_**] instead.
-
-NOTE: Any hardware PWM started by [*hardware_PWM*] will be cancelled.
-D*/
-
 /*F*/
 int wave_send_once(unsigned wave_id);
 /*D
@@ -1207,7 +1184,7 @@ This function transmits a chain of waveforms.
 NOTE: Any hardware PWM started by [*hardware_PWM*] will be cancelled.
 
 The waves to be transmitted are specified by the contents of buf
-which contains an ordered list of wave_ids and optional command
+which contains an ordered list of [*wave_id*]s and optional command
 codes and related data.
 
 . .
@@ -1215,51 +1192,77 @@ codes and related data.
 bufSize: the number of bytes in buf
 . .
 
-Returns 0 if OK, otherwise PI_BAD_REPEAT_CNT, PI_BAD_REPEAT_WID,
-PI_BAD_CHAIN_CMD, PI_TOO_MANY_COUNTS, or PI_BAD_WAVE_ID.
-
-Each wave is transmitted in the order specified.  A wave may only
-occur once per chain.  Waves may be transmitted multiple times by
-using the repeat command.  The repeat command specifies a wave id
-and a count.  The wave id must occur earlier in the chain.  All the
-waves between wave id and the repeat command are transmitted count
-times.
+Returns 0 if OK, otherwise PI_CHAIN_NESTING, PI_CHAIN_LOOP_CNT, PI_BAD_CHAIN_LOOP, PI_BAD_CHAIN_CMD, PI_CHAIN_COUNTER,
+PI_BAD_CHAIN_DELAY, PI_CHAIN_TOO_BIG, or PI_BAD_WAVE_ID.
 
-Repeat commands may not be nested.  The minimum repeat count is 2.
-A maximum of 5 repeat commands is supported per chain.
+Each wave is transmitted in the order specified.  A wave may
+occur multiple times per chain.
 
-The following command codes are supported:
+A blocks of waves may be transmitted multiple times by using
+the loop commands. The block is bracketed by loop start and
+end commands.  Loops may be nested.
 
-Name    @ Cmd & Data       @ Meaning
-Repeat  @ 255 wid C0 C1 C2 @ Repeat from wid count times
-count = C0 + C1*256 + C2*65536
+Delays between waves may be added with the delay command.
 
-...
-The following examples assume that waves with ids 0 to 12 exist.
-
-// 0 255 0 57 0 0 (repeat 0 57 times)
-status = wave_chain((char []){0, 255, 0, 57, 0, 0}, 6);
+The following command codes are supported:
 
-// 0 1 255 0 0 2 0 (repeat 0+1 512 times)
-status = wave_chain((char []){0, 1, 255, 0, 0, 2, 0}, 7);
+Name        @ Cmd & Data @ Meaning
+Loop Start  @ 255 0      @ Identify start of a wave block
+Loop Repeat @ 255 1 x y  @ loop x + y*256 times
+Delay       @ 255 2 x y  @ delay x + y*256 microseconds
 
-// 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
-status = wave_chain((char []){0, 1, 255, 1, 0, 0, 1}, 7);
+The code is currently dimensioned to support a chain with roughly
+600 entries and 20 loop counters.
 
-// 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
-status = wave_chain(
-   (char []){0, 1, 2, 3, 255, 2, 13, 0, 0}, 9);
+...
+#include <stdio.h>
+#include <pigpiod_if.h>
 
-// The following repeats 5 65793 times, transmits 6,
-// repeats 7+8 514 times, transmits 12,
-// repeats 9+11+10 197121 times.
-// 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
-char chain[] = {
-   5,             255, 5, 1, 1, 1,
-   6, 7, 8,       255, 7, 2, 2, 0,
-   12, 9, 11, 10, 255, 9, 1, 2, 3};
+#define WAVES 5
+#define GPIO 4
 
-status = wave_chain(chain, sizeof(chain));
+int main(int argc, char *argv[])
+{
+   int i, wid[WAVES];
+
+   if (pigpio_start(0, 0)<0) return -1;
+
+   set_mode(GPIO, PI_OUTPUT);
+
+   for (i=0; i<WAVES; i++)
+   {
+      wave_add_generic(2, (gpioPulse_t[])
+         {{1<<GPIO, 0,        20},
+          {0, 1<<GPIO, (i+1)*200}});
+
+      wid[i] = wave_create();
+   }
+
+   wave_chain((char []) {
+      wid[4], wid[3], wid[2],       // transmit waves 4+3+2
+      255, 0,                       // loop start
+         wid[0], wid[0], wid[0],    // transmit waves 0+0+0
+         255, 0,                    // loop start
+            wid[0], wid[1],         // transmit waves 0+1
+            255, 2, 0x88, 0x13,     // delay 5000us
+         255, 1, 30, 0,             // loop end (repeat 30 times)
+         255, 0,                    // loop start
+            wid[2], wid[3], wid[0], // transmit waves 2+3+0
+            wid[3], wid[1], wid[2], // transmit waves 3+1+2
+         255, 1, 10, 0,             // loop end (repeat 10 times)
+      255, 1, 5, 0,                 // loop end (repeat 5 times)
+      wid[4], wid[4], wid[4],       // transmit waves 4+4+4
+      255, 2, 0x20, 0x4E,           // delay 20000us
+      wid[0], wid[0], wid[0],       // transmit waves 0+0+0
+
+      }, 46);
+
+   while (wave_tx_busy()) time_sleep(0.1);
+
+   for (i=0; i<WAVES; i++) wave_delete(wid[i]);
+
+   pigpio_stop();
+}
 ...
 D*/
 
diff --git a/pigs.1 b/pigs.1
index 88b8855f4594b46184c087cfc4969434adc71cd7..3dfaad720a872064d907698adbf5d9beb2aed650 100644 (file)
--- a/pigs.1
+++ b/pigs.1
@@ -674,8 +674,8 @@ frequency \fBpf\fP with dutycycle \fBpdc\fP. Frequencies above 30MHz
 are unlikely to work.
 
 .br
-NOTE: Any waveform started by \fBWVGO\fP, \fBWVGOR\fP, \fBWVTX\fP,
-\fBWVTXR\fP, or \fBWVCHA\fP will be cancelled.
+NOTE: Any waveform started by \fBWVTX\fP, \fBWVTXR\fP, or \fBWVCHA\fP
+will be cancelled.
 
 .br
 This function is only valid if the pigpio main clock is PCM.  The
@@ -3125,16 +3125,15 @@ will be returned.
 
 .br
 Each wave is transmitted in the order specified.  A wave may
-only occur once per chain.  Waves may be transmitted multiple
-times by using the repeat command.  The repeat command
-specifies a wave id and a count.  The wave id must occur
-earlier in the chain.  All the waves between wave id and the
-repeat command are transmitted count times.
+occur multiple times per chain.
 
 .br
-Repeat commands may not be nested.  The minimum repeat
-count is 2. A maximum of 5 repeat commands is supported
-per chain.
+A blocks of waves may be transmitted multiple times by using
+the loop commands. The block is bracketed by loop start and
+end commands.  Loops may be nested.
+
+.br
+Delays between waves may be added with the delay command.
 
 .br
 The following command codes are supported:
@@ -3142,11 +3141,16 @@ The following command codes are supported:
 .br
 
 .EX
-Name     Cmd & Data         Meaning
-Repeat   255 wid C0 C1 C2   Repeat from wid count times
+Name          Cmd & Data   Meaning
+Loop Start    255 0        Identify start of a wave block
+Loop Repeat   255 1 x y    loop x + y*256 times
+Delay         255 2 x y    delay x + y*256 microseconds
 
 .EE
-count = C0 + C1*256 + C2*65536
+
+.br
+The code is currently dimensioned to support a chain with roughly
+600 entries and 20 loop counters.
 
 .br
 
@@ -3154,43 +3158,103 @@ count = C0 + C1*256 + C2*65536
 .br
 
 .EX
-The following examples assume that waves with ids 0 to 12 exist.
+#!/bin/bash
 .br
 
 .br
-# 0 255 0 57 0 0 (repeat 0 57 times)
+GPIO=4
 .br
-$ pigs wvcha 0 255 0 57 0 0
+WAVES=5
 .br
 
 .br
-# 0 1 255 0 0 2 0 (repeat 0+1 512 times)
-.br
-$ pigs wvcha 0 1 255 0 0 2 0
+pigs m $GPIO w
 .br
 
 .br
-# 0 1 255 1 0 0 1 (transmit 0, repeat 1 65536 times)
+for ((i=0; i<$WAVES; i++))
+.br
+do
+.br
+   pigs wvag $((1<<GPIO)) 0 20 0 $((1<<GPIO)) $(((i+1)*200))
+.br
+   w[i]=$(pigs wvcre)
 .br
-$ pigs wvcha 0 1 255 1 0 0 1
+done
 .br
 
 .br
-# 0 1 2 3 255 2 13 0 0 (transmit 0+1, repeat 2+3 13 times)
+# transmit waves 4+3+2
+.br
+# loop start
+.br
+#    transmit waves 0+0+0
+.br
+#    loop start
+.br
+#       transmit waves 0+1
+.br
+#       delay 5000us
+.br
+#    loop end (repeat 30 times)
+.br
+#    loop start
+.br
+#       transmit waves 2+3+0
 .br
-$ pigs wvcha 0 1 2 3 255 2 13 0 0
+#       transmit waves 3+1+2
+.br
+#    loop end (repeat 10 times)
+.br
+# loop end (repeat 5 times)
+.br
+# transmit waves 4+4+4
+.br
+# delay 20000us
+.br
+# transmit waves 0+0+0
 .br
 
 .br
-# The following repeats 5 65793 times, transmits 6,
+pigs wvcha \\ 
+.br
+   ${w[4]} ${w[3]} ${w[2]} \\ 
+.br
+   255 0 \\ 
+.br
+      ${w[0]} ${w[0]} ${w[0]} \\ 
+.br
+      255 0 \\ 
+.br
+         ${w[0]} ${w[1]} \\ 
+.br
+         255 2 0x88 0x13 \\ 
+.br
+      255 1 30 0 \\ 
+.br
+      255 0 \\ 
+.br
+         ${w[2]} ${w[3]} ${w[0]} \\ 
+.br
+         ${w[3]} ${w[1]} ${w[2]} \\ 
+.br
+      255 1 10 0 \\ 
 .br
-# repeats 7+8 514 times, transmits 12,
+   255 1 5 0 \\ 
 .br
-# repeats 9+11+10 197121 times.
+   ${w[4]} ${w[4]} ${w[4]} \\ 
 .br
-# 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+   255 2 0x20 0x4E \\ 
 .br
-$ pigs wvcha 5 255 5 1 1 1 6 7 8 255 7 2 2 0 12 9 11 10 255 9 1 2 3
+   ${w[0]} ${w[0]} ${w[0]}
+.br
+
+.br
+while [[ $(pigs wvbsy) -eq 1 ]]; do sleep 0.1; done
+.br
+
+.br
+for ((i=0; i<$WAVES; i++)); do echo ${w[i]}; pigs wvdel ${w[i]}; done
 .br
 
 .EE
@@ -3309,7 +3373,7 @@ ERROR: attempt to create an empty waveform
 .IP "" 4
 
 .br
-This command deletes all waveforms with ids greater than or equal to \fBwid\fP.
+This command deletes the waveform with id \fBwid\fP.
 
 .br
 Upon success nothing is returned.  On error a negative status code
@@ -3336,36 +3400,6 @@ ERROR: non existent wave id
 
 .br
 
-.IP "\fBWVGO \fP - Transmit waveform once (DEPRECATED)"
-.IP "" 4
-
-.br
-This command transmits the current waveform.  The waveform is sent once.
-
-.br
-NOTE: Any hardware PWM started by \fBHP\fP will be cancelled.
-
-.br
-Upon success the number of DMA control blocks in the waveform is returned.
-On error a negative status code will be returned.
-
-.br
-
-.IP "\fBWVGOR \fP - Transmit waveform repeatedly (DEPRECATED)"
-.IP "" 4
-
-.br
-This command transmits the current waveform.  The waveform is sent repeatedly.
-
-.br
-NOTE: Any hardware PWM started by \fBHP\fP will be cancelled.
-
-.br
-Upon success the number of DMA control blocks in the waveform is returned.
-On error a negative status code will be returned.
-
-.br
-
 .IP "\fBWVHLT \fP - Stop waveform"
 .IP "" 4
 
@@ -4059,7 +4093,7 @@ Again, ignore the details for now.
 .br
 
 .EX
-time (pigs procr 0 10000000; while a=$(pigs procp 0); [[ ${a::1} -eq 2 ]];\
+time (pigs procr 0 10000000; while a=$(pigs procp 0); [[ ${a::1} -eq 2 ]];\
 .br
  do sleep 0.2; done)
 .br
@@ -4099,7 +4133,7 @@ jp 999 jumps to tag 999 if the result is positive.
 .br
 
 .EX
-time (pigs procr 0 10000000; while a=$(pigs procp 0); [[ ${a::1} -eq 2 ]];\
+time (pigs procr 0 10000000; while a=$(pigs procp 0); [[ ${a::1} -eq 2 ]];\
 .br
  do sleep 0.2; done)
 .br
index 995ad323c5bd60bc491ae266e8f9ecbf4819cdc0..15bcf6d337a8a434b1a6e5b1de30378514a8efe6 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@
 from distutils.core import setup
 
 setup(name='pigpio',
-      version='1.19',
+      version='1.20',
       author='joan',
       author_email='joan@abyz.co.uk',
       maintainer='joan',
index e3270f959db4cd15c8e2e69579a06ba463e3f004..58a08c25130e3f89ad62337ef4b275fa2119a2f5 100644 (file)
@@ -363,7 +363,7 @@ To the lascivious pleasing of a lute.\n\
       {0, 1<<GPIO, 100000},
    };
 
-   int e, oc, c;
+   int e, oc, c, wid;
 
    char text[2048];
 
@@ -379,7 +379,8 @@ To the lascivious pleasing of a lute.\n\
    e = gpioWaveAddGeneric(4, wf);
    CHECK(5, 2, e, 4, 0, "pulse, wave add generic");
 
-   e = gpioWaveTxStart(PI_WAVE_MODE_REPEAT);
+   wid = gpioWaveCreate();
+   e = gpioWaveTxSend(wid, PI_WAVE_MODE_REPEAT);
    CHECK(5, 3, e, 9, 0, "wave tx repeat");
 
    oc = t5_count;
@@ -399,7 +400,8 @@ To the lascivious pleasing of a lute.\n\
    e = gpioWaveAddSerial(GPIO, BAUD, 8, 2, 5000000, strlen(TEXT), TEXT);
    CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial");
 
-   e = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT);
+   wid = gpioWaveCreate();
+   e = gpioWaveTxSend(wid, PI_WAVE_MODE_ONE_SHOT);
    CHECK(5, 8, e, 6811, 0, "wave tx start");
 
    CHECK(5, 9, 0, 0, 0, "NOT APPLICABLE");
index e0439b6d55904ed497eb8cf126479efa1add8cbc..6435370f3992e5e1eef53e7071fde21fd6dfbcca 100755 (executable)
@@ -356,8 +356,9 @@ To the lascivious pleasing of a lute.
    e = pi.wave_add_generic(wf)
    CHECK(5, 2, e, 4, 0, "pulse, wave add generic")
 
-   e = pi.wave_tx_repeat()
-   CHECK(5, 3, e, 9, 0, "wave tx repeat")
+   wid = pi.wave_create()
+   e = pi.wave_send_repeat(wid)
+   CHECK(5, 3, e, 9, 0, "wave send repeat")
 
    oc = t5_count
    time.sleep(5)
@@ -374,8 +375,9 @@ To the lascivious pleasing of a lute.
    e = pi.wave_add_serial(GPIO, BAUD, TEXT, 5000000)
    CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial")
 
-   e = pi.wave_tx_start()
-   CHECK(5, 8, e, 6811, 0, "wave tx start")
+   wid = pi.wave_create()
+   e = pi.wave_send_once(wid)
+   CHECK(5, 8, e, 6811, 0, "wave send once")
 
    oc = t5_count
    time.sleep(3)
index f782e09d2684c65941c843cd4835b705fc2239d9..750b69743a6df2993f0bce46fc9d9c82c04f9926 100644 (file)
@@ -339,7 +339,7 @@ To the lascivious pleasing of a lute.\n\
       {0, 1<<GPIO, 100000},
    };
 
-   int e, oc, c;
+   int e, oc, c, wid;
 
    char text[2048];
 
@@ -355,7 +355,8 @@ To the lascivious pleasing of a lute.\n\
    e = wave_add_generic(4, wf);
    CHECK(5, 2, e, 4, 0, "pulse, wave add generic");
 
-   e = wave_tx_repeat();
+   wid = wave_create();
+   e = wave_send_repeat(wid);
    CHECK(5, 3, e, 9, 0, "wave tx repeat");
 
    oc = t5_count;
@@ -373,7 +374,8 @@ To the lascivious pleasing of a lute.\n\
    e = wave_add_serial(GPIO, BAUD, 8, 2, 5000000, strlen(TEXT), TEXT);
    CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial");
 
-   e = wave_tx_start();
+   wid = wave_create();
+   e = wave_send_once(wid);
    CHECK(5, 8, e, 6811, 0, "wave tx start");
 
    oc = t5_count;
diff --git a/x_pigs b/x_pigs
index c1d5d1c4bbfaff784dec556db664414ed4eb9421..1f4f36bcf3cc45eb2aa8a00ed41abc3a40f4546e 100755 (executable)
--- a/x_pigs
+++ b/x_pigs
@@ -195,7 +195,9 @@ s=$(pigs wvas $GPIO 1200 8 2 0 0x6d 0x79 0x20 0x6e 0x61 0x6d 0x65 0x20 0x69 0x73
 if [[ $s = 95 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi
 s=$(pigs m $GPIO w)
 if [[ $s = "" ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi
-s=$(pigs wvgo)
+w=$(pigs wvcre)
+if [[ $w -ge 0 ]]; then echo "WVCRE ok"; else echo "WVCRE fail ($s)"; fi
+s=$(pigs wvtx $w)
 if [[ $s = 191 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi
 sleep 0.2
 s=$(pigs slr $GPIO 100)
@@ -246,8 +248,10 @@ s=$(pigs wvas $GPIO 300 8 2 0 0x74 0x68 0x69 0x73 0x20 0x69 0x73 0x20 0x74 0x68
 if [[ $s = 309 ]]; then echo "WVAS ok"; else echo "WVAS fail ($s)"; fi
 s=$(pigs wvag 16 0 5000000 0 16 5000000)
 if [[ $s = 310 ]]; then echo "WVAG ok"; else echo "WVAG fail ($s)"; fi
-s=$(pigs wvgo)
-if [[ $s = 621 ]]; then echo "WVGO ok"; else echo "WVGO fail ($s)"; fi
+w=$(pigs wvcre)
+if [[ $w -ge 0 ]]; then echo "WVCRE ok"; else echo "WVCRE fail ($s)"; fi
+s=$(pigs wvtx $w)
+if [[ $s = 621 ]]; then echo "WVTX ok"; else echo "WVTX fail ($s)"; fi
 s=$(pigs wvbsy)
 if [[ $s = 1 ]]; then echo "WVBSY-a ok"; else echo "WVBSY-a fail ($s)"; fi
 sleep 1
@@ -257,8 +261,8 @@ s=$(pigs wvhlt)
 if [[ $s = "" ]]; then echo "WVHLT ok"; else echo "WVHLT fail ($s)"; fi
 s=$(pigs wvbsy)
 if [[ $s = 0 ]]; then echo "WVBSY-c ok"; else echo "WVBSY-c fail ($s)"; fi
-s=$(pigs wvgor)
-if [[ $s = 621 ]]; then echo "WVGOR ok"; else echo "WVGOR fail ($s)"; fi
+s=$(pigs wvtxr $w)
+if [[ $s = 621 ]]; then echo "WVTXR ok"; else echo "WVTXR fail ($s)"; fi
 s=$(pigs wvbsy)
 if [[ $s = 1 ]]; then echo "WVBSY-d ok"; else echo "WVBSY-d fail ($s)"; fi
 s=$(pigs wvhlt)
diff --git a/x_pipe b/x_pipe
index 9f34589730ed4f1ed52a4e06f466e963b237a0d4..b63c15517270e9e51a534a96086b5f4cd2b4bc53 100755 (executable)
--- a/x_pipe
+++ b/x_pipe
@@ -270,7 +270,10 @@ if [[ $s = 95 ]]; then echo "SLR-c ok"; else echo "SLR-c fail ($s)"; fi
 echo "m $GPIO w" >/dev/pigpio
 read -t 1 s </dev/pigout
 if [[ $s = 0 ]]; then echo "SLR-d ok"; else echo "SLR-d fail ($s)"; fi
-echo "wvgo" >/dev/pigpio
+echo "wvcre" >/dev/pigpio
+read -t 1 w </dev/pigout
+if [[ $w -ge 0 ]]; then echo "WVCRE ok"; else echo "WVCRE fail ($w)"; fi
+echo "wvtx $w" >/dev/pigpio
 read -t 1 s </dev/pigout
 if [[ $s = 191 ]]; then echo "SLR-e ok"; else echo "SLR-e fail ($s)"; fi
 sleep 0.2
@@ -339,9 +342,12 @@ if [[ $s = 215 ]]; then echo "WVAS ok"; else echo "WVAS fail ($s)"; fi
 echo "wvag 16 0 5000000 0 16 5000000" >/dev/pigpio
 read -t 1 s </dev/pigout
 if [[ $s = 216 ]]; then echo "WVAG ok"; else echo "WVAG fail ($s)"; fi
-echo "wvgo" >/dev/pigpio
+echo "wvcre" >/dev/pigpio
+read -t 1 w </dev/pigout
+if [[ $w -ge 0 ]]; then echo "WVCRE ok"; else echo "WVCRE fail ($s)"; fi
+echo "wvtx $w" >/dev/pigpio
 read -t 1 s </dev/pigout
-if [[ $s = 433 ]]; then echo "WVGO ok"; else echo "WVGO fail ($s)"; fi
+if [[ $s = 433 ]]; then echo "WVTX ok"; else echo "WVTX fail ($s)"; fi
 echo "wvbsy" >/dev/pigpio
 read -t 1 s </dev/pigout
 if [[ $s = 1 ]]; then echo "WVBSY-a ok"; else echo "WVBSY-a fail ($s)"; fi
@@ -355,9 +361,9 @@ if [[ $s = 0 ]]; then echo "WVHLT ok"; else echo "WVHLT fail ($s)"; fi
 echo "wvbsy" >/dev/pigpio
 read -t 1 s </dev/pigout
 if [[ $s = 0 ]]; then echo "WVBSY-c ok"; else echo "WVBSY-c fail ($s)"; fi
-echo "wvgor" >/dev/pigpio
+echo "wvtxr $w" >/dev/pigpio
 read -t 1 s </dev/pigout
-if [[ $s = 433 ]]; then echo "WVGOR ok"; else echo "WVGOR fail ($s)"; fi
+if [[ $s = 433 ]]; then echo "WVTXR ok"; else echo "WVTXR fail ($s)"; fi
 echo "wvbsy" >/dev/pigpio
 read -t 1 s </dev/pigout
 if [[ $s = 1 ]]; then echo "WVBSY-d ok"; else echo "WVBSY-d fail ($s)"; fi